什么是“new.target”?

时间:2015-09-08 06:18:38

标签: javascript ecmascript-6

ECMAScript 2015规范提到关键字(或单词?) new.target 正好3次 - 14.2.3中的1次:

  

通常,Contains不会查看大多数函数表单但是,   Contains用于检测 new.target ,这个和超级用法   ArrowFunction。

14.2.16中的两次:

  

ArrowFunction没有为参数定义本地绑定,super,   这个,或 new.target 。对参数的任何引用,super,this或   ArrowFunction中的 new.target 必须解析为a中的绑定   词汇封闭环境

MDN提到它,但非常模糊,页面不完整。

巴别塔似乎不支持它。尝试在函数(箭头或其他)中使用 new.target 时出现语法错误。

它是什么,它应该如何使用?

2 个答案:

答案 0 :(得分:32)

你没有在规范中找到它,因为在语法定义中它是用空格写的new . target。表达式的名称为NewTarget,您可以找到该术语几次。

NewTarget 是第一个所谓的meta properties,可以在§12.3.8中找到。

其唯一目的是retrieve当前(非箭头)函数环境的 [[NewTarget]] 值的当前值。它是在调用函数时设置的值(非常类似于this绑定),并且根据§8.1.1.3 Function Environment Records

  

如果此环境记录是由 [[Construct]] 内部方法创建的, [[NewTarget]] [[Construct]的值] newTarget参数。否则,其值为undefined

所以,首先,我们最终能够检测一个函数是否被调用为构造函数。

但这不是它的真正目的。那么它是什么呢?这是ES6类不仅仅是语法糖,以及它们如何允许我们继承内置对象的方式的一部分。当您通过class调用new X构造函数时,this值尚未初始化 - 在输入构造函数体时尚未创建对象。它确实是在super()调用期间由超级构造函数创建的(当应该创建内部插槽时这是必需的)。尽管如此,实例应该继承自最初调用的构造函数的.prototype,并且 newTarget 进入游戏。它确实拥有在new调用期间收到super()调用的“最外层”构造函数。您可以在规范中一直关注它,但基本上它始终是newTarget而不是当前执行的构造函数,它会传递到OrdinaryCreateFromConstructor procedure - 例如在step 5 of §9.2.2 [[Construct]]中用于用户 - 定义的函数。

长篇文章,也许一个例子更适合:

class Parent {
    constructor() {
        // implicit (from the `super` call)
        //    new.target = Child;
        // implicit (because `Parent` doesn't extend anything):
        //    this = Object.create(new.target.prototype);
        console.log(new.target) // Child!
    }
}
class Child extends Parent {
    constructor() {
        // `this` is uninitialised (and would throw if accessed)
        // implicit (from the `new` call):
        //    new.target = Child 
        super(); // this = Reflect.construct(Parent, [], new.target);
        console.log(this);
    }
}
new Child;

答案 1 :(得分:8)

它主要用于检测何时在没有new的情况下调用构造函数的更好方法。

来自http://www.2ality.com/2015/02/es6-classes-final.html

  

new.target是所有函数都具有的隐式参数。构造函数调用this对方法调用的作用。

所以我可以写:

function Foo() {
  if (!new.target) throw "Foo() must be called with new";
  ...
}

有关其工作原理的详细信息,以及更多有用的背景信息,但我们会将其保留在此处。

有关new.target的一些会议说明,请参阅https://esdiscuss.org/notes/2015-01-27