Why does "new Date().toString()" work given Javascript operator precedence?

javascript, operator-precedence, parsing

Solution

The syntax is

MemberExpression :
    PrimaryExpression
    FunctionExpression
    MemberExpression [ Expression ]
    MemberExpression . IdentifierName
    new MemberExpression Arguments

`new foo().bar` cannot be parsed as `new (foo().bar)` because `foo().bar` is not a MemberExpression. Moreover, `new foo()` cannot be parsed as `new (foo())`, for the same reason. Conversely, `new foo.bar` is parsed as `new (foo.bar)` because `foo.bar` is a valid MemberExpression (an interpretation `(new foo).bar` is impossible because the grammar is greedy).

That is, the precedence rule is: dot beats new, new beats call (parens).

.  -> new -> ()

Furthermore, looking directly at the grammar demystifies the syntactic sugar that turns `new Foo` into `new Foo()`. It's simply NewExpression ← new NewExpression ← new PrimaryExpression:

NewExpression :
    MemberExpression
    new NewExpression

Problem

MDN states that there are two operators in Javscript that share the highest precedence: - The left-associative member operator: `foo.bar` - The right-associative new operator: `new Foo()` I usually explicitly separate the two: `(new Date()).toString()` But I frequently see both of them combined: `new Date().toString()` According to this answer, the reason the second way works is that it's the second operator's associativity that matters when both operators have equal precedence. In this case, the member operator is left associative which means `new Date()` is evaluated first. However, if that's the case, then why does `new Date.toString()` fail? After all, `new Date` is just syntactic sugar for `new Date()`. The above argument says it should work, but it obviously doesn't. What am I missing?

Original source

Related problems