【问题标题】:super() does not pass arguments when instantiating a class extended from Object in Chrome V8在 Chrome V8 中实例化从 Object 扩展的类时,super() 不传递参数
【发布时间】:2016-03-24 15:13:23
【问题描述】:

下面的代码在 Chrome V8 中记录为 false,但在 Babel 中记录为 true。 feedback from Google 说记录 false 是应该的,而记录 true 是 Babel 的错误。我查看了 ES6 规范,但仍然无法理解其背后的机制。任何想法将不胜感激!

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);

【问题讨论】:

  • 我不明白对那个错误的反应; super() 调用肯定允许包含参数列表,并且 Object 构造函数应该注意它的参数。
  • 这是一个 Chromium 错误。我已经在 Microsoft Edge 上进行了测试。它返回true

标签: javascript google-chrome ecmascript-6 v8 babeljs


【解决方案1】:

事实上,您对 Chrome 错误的反馈是正确的。从 ES5 到 ES6,有些事情确实发生了变化。 Babel 对此无能为力,Edge 也没有改变它。或者这是一个错误:-)

ES5 new Object(value) 规范说它返回一个传入的对象值。

在 ES6 中,您必须检查 [[construct]] of builtinsObject(value) function 上的部分。第一个陈述是

如果 NewTarget 既不是undefined 也不是活动函数,那么
返回OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%")。

所以如果你在做new Object({…}),它仍然会返回{…} 参数。但是,当你从super()Reflect.construct(Object, [{…}], MyCustomTarget) 调用它时,new.target 不是Object,那么你只会得到一个从MyCustomTarget.prototype 构造的新对象,并且参数被忽略。

【讨论】:

  • 很好的发现。不得不想知道为什么从 5->6 改变,因为你真的希望它按照 OPs 代码工作。
  • @JamesThorpe:嗯,它并没有从 ES5 真正改变,因为 ES5 没有超级调用/new.target。简单地调用new Object(…) 仍然像往常一样工作。只是从子类来看,Object 的工作方式与“正常”相比不同
  • 对,是的——这很有道理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 2015-02-01
  • 2015-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多