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 时出现语法错误。
它是什么,它应该如何使用?
答案 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。