8

The code below logs false in Chrome V8 but logs true in Babel. The feedback from Google said that logging false is how it is supposed to be while logging true is a bug of Babel. I looked into the ES6 specs and still couldn't understand the mechanism behind this. Any thoughts would be appreciated!

class NewObj extends Object{
  constructor(){
    super(...arguments); // In V8, after arguments === [{attr: true}]
                         // is passed as parameter to super(),
                         // this === NewObj{} in V8; 
                         // but this === NewObj{attr: true} in Babel.
  }
}
var o = new NewObj({attr: true});
console.log(o.attr === true);
2
  • 2
    I don't understand the response to that bug; a super() call is most certainly allowed to include an argument list, and the Object constructor is supposed to pay attention to its argument.
    – Pointy
    Mar 24, 2016 at 15:27
  • 1
    It's a Chromium bug. I've tested on Microsoft Edge. It returns true.
    – Lewis
    Mar 24, 2016 at 15:35

1 Answer 1

9

In fact the feedback you got on that Chrome bug is correct. Some things did change here from ES5 to ES6. Babel can't really do anything about it, and Edge didn't yet change it. Or it's an erratum :-)

The ES5 new Object(value) spec says that it returns an object value that is passed in.

In ES6, you have to check the sections on [[construct]] of builtins and the Object(value) function. And the first statement of that is

If NewTarget is neither undefined nor the active function, then
Return OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%").

So if you are doing new Object({…}), it will still return the {…} argument. But when you are calling it from super() or as Reflect.construct(Object, [{…}], MyCustomTarget), so that new.target is not Object, then you'll just get a new object constructed from MyCustomTarget.prototype, and the argument is ignored.

3
  • Good find. Have to wonder why the change from 5->6, since you really would expect it to work as per the OPs code. Mar 24, 2016 at 16:04
  • 1
    @JamesThorpe: Well, it didn't really change from ES5, because ES5 did not have super calls/new.target. Plainly invoking new Object(…) still works as always. It's just that from subclasses, Object works differently than "normal".
    – Bergi
    Mar 24, 2016 at 16:06
  • Right, yes - that makes sense. Mar 24, 2016 at 16:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.