¿Qué es "nuevo.objetivo"?

Resuelto Amit asked hace 9 años • 2 respuestas

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

Normalmente, Contiene no busca dentro de la mayoría de los formularios de funciones. Sin embargo, Contiene se usa para detectar new.target , this y super uso dentro de una ArrowFunction.

y dos veces en 14.2.16 :

Una ArrowFunction no define enlaces locales para argumentos, super, this o new.target . Cualquier referencia a argumentos, super, this o new.target dentro de una ArrowFunction debe resolverse en un enlace en un entorno léxico adjunto.

MDN lo 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 debe utilizar?

Amit avatar Sep 08 '15 13:09 Amit
Aceptado

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

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

Su único propósito es recuperar el valor actual del valor [[NewTarget]] del entorno de función actual (sin flecha). Es un valor que se establece cuando se llama a una función (muy parecido al thisenlace) y de acuerdo con §8.1.1.3 Registros del entorno de funciones :

Si este Registro de Entorno fue creado por el método interno [[Construct]] , [[NewTarget]] es el valor del parámetro [[Construct]] newTarget . En caso contrario su valor es undefined.

Entonces, por un lado, finalmente nos permite detectar si una función fue llamada 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 de cómo nos permiten heredar de objetos integrados. Cuando llama a un classconstructor a través de new X, el thisvalor aún no está inicializado: el objeto aún no se ha creado cuando se ingresa el cuerpo del constructor. El superconstructor lo crea durante la super()llamada (lo cual es necesario cuando se supone que se crean ranuras internas). Aún así, la instancia debe heredar del .prototypeconstructor llamado originalmente, y ahí es donde entra en juego newTarget . Contiene el constructor "más externo" que recibió la newllamada durante super()las invocaciones. Puede seguirlo hasta el final en la especificación, pero básicamente siempre es el newTargetconstructor que no se ejecuta actualmente el que se pasa al OrdinaryCreateFromConstructorprocedimiento ; por ejemplo, en el paso 5 de §9.2.2 [[Construct]] para definido por el usuario. funciones.

Texto largo, quizás un ejemplo sea 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;
Bergi avatar Sep 08 '2015 13:09 Bergi

Su objetivo principal es ser 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.targetes un parámetro implícito que tienen todas las funciones. Son las llamadas al constructor lo que thisson las llamadas al 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 obtener algunas notas de la reunión sobre new.target, consulte https://esdiscuss.org/notes/2015-01-27 .

 avatar Sep 08 '2015 06:09