skip to Main Content

I have a factory that creates a new entity and it calls new Date() multiple times to fill multiple fields like shown below:

  dateJoined: format('yyyy-MM-dd')(new Date()),
  createdAt: new Date().toISOString(),
  updatedAt: new Date().toISOString()

one of my senior engineers suggested saving new Date() in a const and using it instead of calling new Date() multiple times, so the above code would change to be like this:

  const date = new Date();
  dateJoined: format('yyyy-MM-dd')(date),
  createdAt: date.toISOString(),
  updatedAt: date.toISOString()

He mentioned that one of the reasons for calling new Date() one time only is that there might be a millisecond difference between dates if we call it multiple times.

I am curious how likely is that to happen? and are there other benefits to calling new Date() one time only?

4

Answers


  1. Using a single new Date() instance stored in a constant is generally a good practice.

    • First, it ensures consistency across your dateJoined, createdAt, and updatedAt fields, as there can be millisecond differences between consecutive new Date() calls, as you said.
    • Second, it slightly improves performance by reducing the load associated with creating multiple Date objects (few milliseconds, not that much but depends on your project and how many times you call it)
    • Lastly, this approach enhances code readability and maintainability: centralizing one and only one date.
    Login or Signup to reply.
  2. I tried it in my browser using this script:

    var diff=0;
    for (var i=0; i<10000; i++) {
        var d1=new Date();
        var d2=new Date();
        var d3=new Date();
        if (d1.getTime()!=d2.getTime() || d1.getTime()!=d3.getTime()) { 
            diff++;
        }
    }
    console.log(diff);

    and there are some iterations where the three dates are not equal. Typically, around 8 per 10000.

    This is exactly the kind of inconsistency that passes many test runs but almost inevitably will bite you in production. Avoid it and follow your senior’s advice.

    Login or Signup to reply.
  3. In your example you store formatted string in your object properties.
    So it’s totally OK to use the same date like your senior dev suggested.

    But in general the most important is mutability. The problem is Date isn’t a primitive and is mutable.
    So if in your example the dates would be stored as dates it is quite risky suggesting to use the same Date for different semantic values.

    If you mutate some date for example obj.createdAt.setMinutes(0, 0, 0) you essentially change updatedAt.
    So the thumb of rule is to have Date immutable.

    You can use any date library that operates on dates in immutable way.
    Creating new Date is quite fast process and it isn’t worth to have duplicated dates to have some speed optimizations in expense of risks of having dangerous side effects because of mutability.

    If you want to use a Date in another variable just clone it new Date(dt). Never have copies of dates and treat them as immutable primitives.

    Regarding your example you can even optimize it further:

    const date = new Date().toISOString();
    
    const obj = {
      dateJoined: date.slice(0, 10),
      createdAt: date,
      updatedAt: date
    };
    
    console.log(obj);
    Login or Signup to reply.
  4. Your senior engineer is right actually, It’s best practice to create a single Date object and use it again for the following reasons and many more:

    Performance: By not instantiating new objects frequently, you avoid the unnecessary overhead of repeatedly instantiating new objects.

    Maintainability: if you ever need to adjust the format of the dates or take care of any date manipulation-related changes, you just need to do it once.

    Preventing Bugs: Mistakes will need to be fixed each time it happens. It is less likely to introduce problems and easier to manage and update the code when there is only one constant.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search