Come posso distinguere tra una funzione freccia, una class e una funzione normale?

Come posso differenziare tra queste tre cose in ES6 usando il suo riferimento?

let x = i => i+1; class y { constructor(i) { this._i=i+1; } get i(){ return this._i;} } function z(i) { return i+1; } 

Esempio:

 test(x) //=> 'arrow' test(y) //=> 'class' test(z) //=> 'function' 

E come posso differenziare tra queste cose nei transporter – Traceur / Babel?

Come posso differenziare tra queste cose in ES6?

  • le funzioni freccia sono funzioni che non possono essere utilizzate come costruttori e che non hanno una proprietà .prototype . Tuttavia, i metodi non lo fanno neanche. Essi ereditano da Function.prototype .
  • le classi sono funzioni che non possono essere chiamate senza new e che hanno un object .prototype che normalmente non è vuoto. Se è stata utilizzata la parola chiave extends , non ereditano da Function.prototype .
  • le funzioni sono funzioni che possono essere chiamate in entrambi i modi e hanno un .prototype che è normalmente vuoto . Essi ereditano da Function.prototype .
  • le funzioni del generatore sono funzioni che hanno un .prototype che eredita dall’object intrinseco GeneratorPrototype e che ereditano dall’object intrinseco del Generatore .

Come puoi vedere, ci sono alcuni indizi. Tuttavia, le proprietà e l’ereditarietà possono sempre essere incasinate, quindi non ci si può davvero fidare. Se una funzione è un costruttore (può essere chiamata con una new ) non può essere determinata dall’esterno, devi chiamarla e vedere se getta – che potrebbe essere falsificata pure.

Quindi la soluzione migliore potrebbe essere Function.prototype.toString , per vedere come appariva la sorgente. Se la tua implementazione ES lo supporta.

E come posso differenziare tra queste cose nei transporter?

Non penso che nessun transpiler implementa frecce e metodi senza prototipo. Il fatto che un costruttore di class lanci quando viene chiamato dipende dalla scioltezza della transpilation, ma non è comunque un buon modo per distinguere.
toString non funziona neanche afaik.

Non puoi trasformare i primi due casi in questo:

 var x = function x(i) { return i + 1; }; function z(i) { return i + 1; } 

Per l’ultimo potresti verificare se si lamenta se è una class quando la chiami:

 function isClass(instance){ try{ instance() }catch(e){ return e.message === "Cannot call a class as a function"; } return false; } 

Ma ciò ovviamente innescherà gli effetti collaterali della chiamata, quindi non funziona nel caso generale.