Javascript “什么是”呢;新的。目标;?
ECMAScript 2015规范中提到关键字(或单词?new.target的次数正好为3次-1次: 通常情况下,Contains不会查看大多数函数形式的内部, Contains用于检测新的.target、this和super在 箭头功能 两次在: ArrowFunction不为参数定义本地绑定,super, 这个,或新建。目标。对参数、super、this或 新建。arrow函数中的目标必须解析为 词汇封闭环境 提到它,但非常模糊,页面不完整 巴贝尔似乎并不支持。尝试在函数(箭头或其他)中使用new.target时出现语法错误Javascript “什么是”呢;新的。目标;?,javascript,ecmascript-6,Javascript,Ecmascript 6,ECMAScript 2015规范中提到关键字(或单词?new.target的次数正好为3次-1次: 通常情况下,Contains不会查看大多数函数形式的内部, Contains用于检测新的.target、this和super在 箭头功能 两次在: ArrowFunction不为参数定义本地绑定,super, 这个,或新建。目标。对参数、super、this或 新建。arrow函数中的目标必须解析为 词汇封闭环境 提到它,但非常模糊,页面不完整 巴贝尔似乎并不支持。尝试在函数(箭头或其他)中使用
它是什么,应该如何使用?它主要是为了更好地检测何时调用构造函数而不使用
new
发件人:
new.target
是所有函数都具有的隐式参数。构造函数调用的作用与方法调用的作用类似
所以我可以写:
function Foo() {
if (!new.target) throw "Foo() must be called with new";
...
}
关于它的工作原理有更多的细节,在更多的上下文中它是有用的,但我们将把它留在这里
有关
new.target
的一些会议说明,请参阅。您在规范中找不到它,因为在语法定义中它是用空格编写的,如new。目标
。表达式的名称是NewTarget
,您可以多次找到该术语
新目标是第一个所谓的目标,见§12.3.8
它的唯一用途是为当前(非箭头)函数环境的[[NewTarget]]值的当前值设置。它是一个在调用函数时设置的值(非常类似于此
绑定),并根据以下条件设置:
如果此环境记录是由[[Construct]]内部方法创建的,[[NewTarget]]是[[Construct]]NewTarget
参数的值。否则,其值为未定义
因此,首先,它最终使我们能够检测函数是否作为构造函数调用
但这不是它的真正目的。那又是什么呢?这是ES6类如何不仅仅是语法糖的一部分,以及它们如何允许我们从内置对象继承。当您通过new X
调用类
构造函数时,此
值尚未初始化-输入构造函数主体时,对象尚未创建。它确实是由超级构造函数在super()
调用期间创建的(这在应该创建内部插槽时是必需的)。不过,该实例应该继承最初调用的构造函数的.prototype
,这就是newTarget发挥作用的地方。它确实包含在super()
调用期间接收new
调用的“最外层”构造函数。您可以在规范中一直遵循它,但基本上,传递到中的始终是newTarget
,而不是当前执行的构造函数,例如在for用户定义函数中
长文本,也许一个例子更适合:
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;
我认为在没有
new
的情况下调用构造函数是不可能的(你会得到一个异常)。除非你说的“构造函数”是指用“new”调用的常规函数,我只是误解了你的意思。@Asad构造函数是用new
调用的常规函数。我明白了。我是从新的ES6构造函数的意义上考虑它的,如果不使用new
调用它们,它会出现类型错误。规范中定义了哪些呢?@Amit我说的是经典意义上的函数Foo()
的构造函数。这意味着它的有效语法可以写入console.log(new.target)
(带空格)在一个函数中?@Amit:我猜-它是多个标记,总是可以通过空格分隔。写入console.log(…)
也是有效的:-)当然没有人这样做-除了方法链接时的换行符…但这并不完全相同<代码>控制台
是一个标识符,新建
是一个关键字。当考虑到new Obj()
是有效语法时,这会让人觉得很奇怪。@Asad:在调用super()
之前,您无法访问this
——当您尝试引用它时,它抛出一个ReferenceError
@Maximus不是子构造函数,而是子构造函数本身。我们希望新实例继承自Child.prototype
对象