什么是“new.target"? [英] What is "new.target"?

查看:46
本文介绍了什么是“new.target"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ECMAScript 2015 规范在 14.2.3:

The ECMAScript 2015 specification mention the keyword (or words?) new.target exactly 3 times - 1 time in 14.2.3:

通常,Contains 不会查看大多数函数形式的内部 但是,contains 用于检测 new.target、this 和 super 在一个箭头函数.

Normally, Contains does not look inside most function forms However, Contains is used to detect new.target, this, and super usage within an ArrowFunction.

和两次在 14.2.16:

ArrowFunction 没有为参数、super、这个,或new.target.任何对参数、super、this 或ArrowFunction 中的 new.target 必须解析为词法封闭环境

An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment

MDN 提到了它,但非常含糊和页面不完整.

MDN mentions it, but is very vague and the page is incomplete.

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

Babel doesn't seem to support it. I got syntax errors when trying to use new.target in a function (arrow or others).

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

What is it, and how is it supposed to be used?

推荐答案

您没有在规范中找到它,因为在语法定义中它是用空格编写的,如 new .目标.表达式的名称是 NewTarget,您会多次发现该术语.

You didn't find it in the spec because in the syntax definitions it is written with blanks, as new . target. The name of the expression is NewTarget, and you'll find that term a few times around.

NewTarget 是第一个所谓的 元属性,可以在 §12.3.8 中找到.

NewTarget is the first of the so-called meta properties and can be found in §12.3.8.

它的唯一目的是检索当前值当前(非箭头)函数环境的 [[NewTarget]] 值.它是在调用函数时设置的值(非常类似于 this 绑定),并且根据 §8.1.1.3 函数环境记录:

Its sole purpose is to retrieve the current value of the [[NewTarget]] value of the current (non-arrow) function environment. It is a value that is set when a function is called (very much like the this binding), and according to §8.1.1.3 Function Environment Records:

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

If this Environment Record was created by the [[Construct]] internal method, [[NewTarget]] is the value of the [[Construct]] newTarget parameter. Otherwise, its value is undefined.

所以,一方面,最终使我们能够检测一个函数是否作为构造函数被调用.

So, for one thing, finally enables us to detect whether a function was called as a constructor or not.

但这不是它的真正目的.那么到底是什么呢?ES6 类不仅是语法糖,也是它们如何允许我们从内置对象继承的方式的一部分.当您通过 new X 调用 class 构造函数时,this 值尚未初始化 - 当构造函数主体处于进入.它确实在 super() 调用期间由超级构造函数创建(这在应该创建内部插槽时是必需的).尽管如此,该实例应该从最初调用的构造函数的 .prototype 继承,这就是 newTarget 发挥作用的地方.它确实保存了在 super() 调用期间接收 new 调用的最外层"构造函数.您可以在规范中一直遵循它,但基本上它总是 newTarget 而不是当前执行的构造函数,它确实被传递到 OrdinaryCreateFromConstructor 过程 - 例如在 第 5 步第 §9.2.2 [[Construct]] 用于用户定义的函数.

But that's not its real purpose. So what is it then? It is part of the way how ES6 classes are not only syntactic sugar, and how they allow us inheriting from builtin objects. When you call a class constructor via new X, the this value is not yet initialised - the object is not yet created when the constructor body is entered. It does get created by the super constructor during the super() call (which is necessary when internal slots are supposed to be created). Still, the instance should inherit from the .prototype of the originally called constructor, and that's where newTarget comes into the play. It does hold the "outermost" constructor that received the new call during super() invocations. You can follow it all the way down in the spec, but basically it always is the newTarget not the currently executed constructor that does get passed into the OrdinaryCreateFromConstructor procedure - for example in step 5 of §9.2.2 [[Construct]] for user-defined functions.

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

Long text, maybe an example is better suited:

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.target"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆