Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are operators in the expression new Date().getTime() applied in strict left-to-right order?

The following expression seems to work as intended and return the current timestamp.

new Date().getTime()

However I can't understand why operators are applied in strict left-to-right order here.

MDN says the member (.) operator has higher priority than new. This would mean that . must be applied before new. So the expression should be evaluated as:

new (Date().getTime())

But in fact it is evaluated as:

(new Date()).getTime()

I guess there has to be something I've overlooked, but I can't understand what.

Note: I don't actually use this expression (I prefer Date.now() method). It's just my curiosity.

like image 618
hindmost Avatar asked Sep 17 '15 13:09

hindmost


1 Answers

The MDN precedence table isn't really correct; the new operator and the property access operators are all part of the MemberExpression non-terminal in the grammar. Since they're left-associative operators,

new something.something

is evaluated as

(new something).something

Here is the relevant part of the spec.

Therefore in your sample expression

new Date().getTime()

the whole left side of the . is parsed as a MemberExpression. What kind of MemberExpression is it? It's a new MemberExpression production, so that's deeper into the parse tree and that gives us the left-associative behavior.

edit — something else I just thought of. Let's say we have an object:

var obj = {
  findConstructor: function(name) {
    return window[name];
  }
};

Now, let's try that expression to get the time using this object:

new obj.findConstructor("Date")().getTime()

That'll give you an error. (I'm on thin ice here:) That's because it parses that as

new (obj.findConstructor("Date")().getTime)()

which clearly won't work. Instead, you have to add explicit parentheses:

(new obj.findConstructor("Date")()).getTime()
like image 85
Pointy Avatar answered Oct 14 '22 05:10

Pointy