7

I would like to know if expressions of the form new super.SomeProperty are valid in JavaScript.

This question arose while working with code that behaves inconsistently across browsers like the example in the snippet below.

class Test {
    test() {
        return new super.constructor;
    }
}

console.log((new Test).test());

This prints an empty object in Firefox and Edge but throws a ReferenceError in Chrome and a SyntaxError in Safari. The error can be easily circumvented putting parentheses around super.constructor or using a variable, so it's not a real limitation, rather a matter of curiosity about the language itself. I checked the spec but couldn't find anything implying that an error should be thrown in this case, so it's likely that I'm missing something.

GOTO 0
  • 42,323
  • 22
  • 125
  • 158
  • 1
    Well [`class`es aren't supported by IE at all](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Browser_compatibility). There are [many JS standards](https://en.wikipedia.org/wiki/ECMAScript) these days with varying support (mainly ruined by IE). I'd advise using a precompiler like [Babel](https://babeljs.io/) if you want to use ECMAScript 2015 defintions. – Liam May 11 '18 at 09:13
  • 2
    It's not clear for me if the dot in `new super.constructor`, which is defined in [superPropertyReference](https://tc39.github.io/ecma262/#sec-makesuperpropertyreference), should have the same operator precendence as the member access operator [superPropertyReference](https://tc39.github.io/ecma262/#sec-makesuperpropertyreference). – Denys Séguret May 11 '18 at 09:19
  • 2
    And I didn't find anything in the spec about how `super` should behave in the context of `new ...`. IMO. this is a case of unspecified behaviour – Thomas May 11 '18 at 09:34

1 Answers1

3

According to MDN Operator precedence article new without argument list is lower than member access. This suggests that new super.constructor should be evaluated as new (super.constructor) and Firefox and Edge are correct.

Now, according to the specs:

new super.constructor is new NewExpression (https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-new-operator). NewExpression is in form of MemberExpression, which is in form of SuperProperty which is in form of super.IdentifierName. ES6 standard seems to say the same. So it seems to me that MDN is correct, and so Firefox and Edge are compliant with the spec.

user3840170
  • 26,597
  • 4
  • 30
  • 62
Andrew Svietlichnyy
  • 743
  • 1
  • 6
  • 13
  • The whole answer turns around "NewExpression is in form of MemberExpression,". Can you precise the reference ? – Denys Séguret May 11 '18 at 09:58
  • @DenysSéguret Specification has links everywhere. I take https://tc39.github.io/ecma262/#sec-new-operator that the new operator should eat everything that qualifies as MemberExpression until it finds Arguments. – Andrew Svietlichnyy May 11 '18 at 10:12
  • @AndrewSvietlichnyy that's also the result of operator precedence rules but the hole I couldn't fill is "Is super.constructor a MemberExpression?". That would make sense of course but I think the question is about specification. – Denys Séguret May 11 '18 at 10:14
  • @DenysSéguret Isn't `constructor` just a regular property name? Chrome parses `new super.constructor` as `(new super).constructor` and `new super` isn't valid syntax because `super` is neither NewEpxression nor MemberExpression. – Andrew Svietlichnyy May 11 '18 at 10:21
  • No it isn't: look at this: https://tc39.github.io/ecma262/#sec-makesuperpropertyreference – Denys Séguret May 11 '18 at 10:24
  • Chrome evaluates `return new (super.constructor)` just fine. `super.constructor` is just the same MemberExpression as `super.randomPropertyName` (https://tc39.github.io/ecma262/#prod-MemberExpression). Right, and Chrome doesn't raise a syntax error, so for some strange reason it doesn't resolve that reference. – Andrew Svietlichnyy May 11 '18 at 11:01