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 quethis
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 valorundefined
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;