Le specifiche di ECMAScript 2015 menzionano la parola chiave (o le parole?) New.target esattamente 3 volte – 1 volta in 14.2.3 :
Normalmente, Contains non guarda nella maggior parte dei moduli di funzione. Tuttavia, Contains viene utilizzato per rilevare new.target , questo e l’uso super all’interno di ArrowFunction.
- Perché dovrei usare le classi ES6?
- Accesso all'indice degli elementi dell'array ES6 all'interno del ciclo for-of
- Diffusione degli oggetti contro Object.assign
- reactjs che dà errore Uncaught TypeError: Super expression deve essere nullo o una funzione, non indefinita
- Javascript: qual è la differenza tra funzione e class
e due volte in 14.2.16 :
Una ArrowFunction non definisce binding locali per argomenti, super, this o new.target . Qualsiasi riferimento agli argomenti, super, this o new.target all’interno di ArrowFunction deve risolversi in un binding in un ambiente che racchiude lessicalmente
La MDN lo menziona, ma è molto vago e la pagina è incompleta.
Babel non sembra supportarlo. Ho avuto errori di syntax durante il tentativo di utilizzare new.target in una funzione (freccia o altro).
Cos’è e come dovrebbe essere usato?
Non l’hai trovato nelle specifiche perché nelle definizioni di syntax è scritto con spazi vuoti, come new . target
new . target
. Il nome dell’espressione è NewTarget
, e troverai quel termine un po ‘di volte.
NewTarget è la prima delle cosiddette proprietà meta e può essere trovata in §12.3.8.
Il suo unico scopo è quello di recuperare il valore corrente del valore [[NewTarget]] dell’ambiente di funzionamento corrente (non-freccia). È un valore che viene impostato quando viene chiamata una funzione (molto simile a this
associazione) e in base al §8.1.1.3 Record di ambiente della funzione :
Se questo Record Ambiente è stato creato dal metodo interno [[Costrutto]] , [[NuovoTarget]] è il valore del parametro [[Costrutto]]
newTarget
. Altrimenti, il suo valoreundefined
èundefined
.
Quindi, per prima cosa, finalmente ci consente di rilevare se una funzione è stata chiamata come costruttore o no.
Ma questo non è il suo vero scopo. Allora cos’è allora? Fa parte del modo in cui le classi ES6 non sono solo zucchero sintattico e in che modo ci consentono di ereditare dagli oggetti incorporati. Quando si chiama un costruttore di class
tramite la new X
, this
valore non è ancora stato inizializzato – l’object non è ancora stato creato quando viene immesso il corpo del costruttore. Viene creato dal super costruttore durante la chiamata a super()
(che è necessario quando devono essere creati slot interni). Tuttavia, l’istanza dovrebbe ereditare dal .prototype
del costruttore originariamente chiamato, ed è qui che entra in gioco newTarget . Sostiene il costruttore “più esterno” che ha ricevuto la new
chiamata durante le invocazioni super()
. Puoi seguirlo fino in fondo nelle specifiche, ma in fondo è sempre il nuovo newTarget
non il costruttore attualmente eseguito che viene passato nella procedura OrdinaryCreateFromConstructor
– ad esempio nel passaggio 5 di §9.2.2 [[Costruisci]] per l’utente funzioni definite.
Testo lungo, forse un esempio è più adatto:
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;
È principalmente inteso come un modo migliore per rilevare quando un costruttore viene chiamato senza new
.
Da http://www.2ality.com/2015/02/es6-classs-final.html :
new.target
è un parametro implicito che tutte le funzioni hanno. È al costruttore che chiama ciò che è per le chiamate di metodo.
Quindi posso scrivere:
function Foo() { if (!new.target) throw "Foo() must be called with new"; ... }
Ci sono più dettagli su come funziona e più contesti in cui è utile, ma lo lasceremo qui.
Per alcune note di incontro riguardanti new.target
, vedere https://esdiscuss.org/notes/2015-01-27 .