¿Qué es "nuevo.objetivo"?
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?
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 NewTarget
y 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 this
enlace) 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 esundefined
.
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 class
constructor a través de new X
, el this
valor 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 .prototype
constructor llamado originalmente, y ahí es donde entra en juego newTarget . Contiene el constructor "más externo" que recibió la new
llamada durante super()
las invocaciones. Puede seguirlo hasta el final en la especificación, pero básicamente siempre es el newTarget
constructor que no se ejecuta actualmente el que se pasa al OrdinaryCreateFromConstructor
procedimiento ; 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;
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.target
es un parámetro implícito que tienen todas las funciones. Son las llamadas al constructor lo quethis
son 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 .