support ecmascript javascript ecmascript-6

javascript - ecmascript 6 support



¿Qué es "new.target"? (2)

La especificación ECMAScript 2015 menciona la palabra clave (¿o palabras?) New.target exactamente 3 veces - 1 vez en 14.2.3 :

Normalmente, Contains no se ve dentro de la mayoría de las formas de función. Sin embargo, Contains se usa para detectar new.target , this y super use dentro de ArrowFunction.

y dos veces en 14.2.16 :

Una función de flecha no define enlaces locales para argumentos, super, this o new.target . Cualquier referencia a argumentos, super, this o new.target dentro de una función de flecha debe resolver un enlace en un entorno léxico.

MDN menciona, pero es muy vago y la página está incompleta.

Babel no parece apoyarlo. Recibí errores de sintaxis al intentar usar new.target en una función (flecha u otras).

¿Qué es y cómo se supone que debe usarse?


Está pensado principalmente como una mejor manera de detectar cuándo se llama a un constructor sin new .

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

new.target es un parámetro implícito que tienen todas las funciones. Es a las llamadas de constructor lo que this es a las llamadas de método.

Entonces puedo escribir:

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

Hay más detalles sobre cómo funciona esto y más contextos en los que es útil, pero lo dejaremos aquí.

Para algunas notas de la reunión con respecto a new.target , consulte https://esdiscuss.org/notes/2015-01-27 .


No lo encontró en la especificación porque en las definiciones de sintaxis está escrito con espacios en blanco, como new . target new . target . El nombre de la expresión es NewTarget , y encontrará ese término varias veces.

NewTarget es la primera de las llamadas meta propiedades y se puede encontrar en §12.3.8.

Su único propósito es retrieve el valor actual del valor [[NewTarget]] del entorno de la función actual (sin flecha). Es un valor que se establece cuando se llama a una función (muy similar a this enlace), y de acuerdo con §8.1.1.3 Registros de entorno de función :

Si este Registro de entorno fue creado por el método interno [[Construir]] , [[NewTarget]] es el valor del parámetro [[Construir]] newTarget . De lo contrario, su valor undefined está undefined .

Entonces, por un lado, finalmente nos permite detectar si una función se llamó como constructor o no.

Pero ese no es su verdadero propósito. Entonces, que es? Es parte de la forma en que las clases de ES6 no son solo azúcar sintáctica, y cómo nos permiten heredar de los objetos incorporados. Cuando llama a un constructor de class través de una new X , this valor aún no se inicializa: el objeto aún no se crea cuando se ingresa el cuerpo del constructor. El superconstructor lo crea durante la llamada super() (que es necesaria cuando se supone que se crean ranuras internas). Aún así, la instancia debe heredar del .prototype del constructor originalmente llamado, y ahí es donde newTarget entra en juego. Contiene el constructor "más externo" que recibió la new llamada durante super() invocaciones super() . Puede seguirlo hasta abajo en la especificación, pero básicamente siempre es el newTarget no el constructor ejecutado actualmente, el que se pasa al procedimiento OrdinaryCreateFromConstructor , por ejemplo, en el paso 5 de §9.2.2 [[Construir]] para el usuario Funciones definidas.

Texto largo, tal vez un ejemplo es más adecuado:

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;