tl; dr: No! Le funzioni freccia e le dichiarazioni / espressioni di funzione non sono equivalenti e non possono essere sostituite alla cieca.
Se la funzione che si desidera sostituire non non usare this
, arguments
e non viene chiamato con new
, allora sì.
Come spesso: dipende . Le funzioni freccia hanno un comportamento diverso rispetto alle dichiarazioni / espressioni di funzioni, quindi diamo prima un'occhiata alle differenze:
1. Lessico this
earguments
Le funzioni freccia non hanno le proprie this
o le arguments
associazioni. Invece, tali identificatori vengono risolti nell'ambito lessicale come qualsiasi altra variabile. Ciò significa che all'interno di una funzione freccia, this
e si arguments
riferiscono ai valori di this
e arguments
nell'ambiente la funzione freccia è definita in (cioè "al di fuori" della funzione freccia):
// Example using a function expression
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: function() {
console.log('Inside `bar`:', this.foo);
},
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
// Example using a arrow function
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: () => console.log('Inside `bar`:', this.foo),
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
Nel caso dell'espressione della funzione, si this
riferisce all'oggetto creato all'interno di createObject
. Nel caso funzione freccia, this
si riferisce al this
di createObject
sé.
Ciò rende utili le funzioni freccia se è necessario accedere this
all'ambiente corrente:
// currently common pattern
var that = this;
getData(function(data) {
that.data = data;
});
// better alternative with arrow functions
getData(data => {
this.data = data;
});
Si noti che ciò significa anche che non è possibile impostare una funzione freccia this
con .bind
o .call
.
Se non hai molta familiarità this
, considera la lettura
2. Le funzioni freccia non possono essere richiamate con new
ES2015 distingue tra funzioni abilitabili alla chiamata e funzioni costruibili . Se una funzione è costruibile, può essere chiamata con new
, ad es new User()
. Se una funzione è richiamabile, può essere richiamata senza new
(cioè chiamata di funzione normale).
Le funzioni create tramite dichiarazioni / espressioni di funzioni sono sia costruibili che richiamabili.
Le funzioni (e i metodi) delle frecce sono solo richiamabili.
class
i costruttori sono costruibili solo.
Se si sta tentando di chiamare una funzione non richiamabile o di costruire una funzione non costruibile, verrà visualizzato un errore di runtime.
Sapendo questo, possiamo affermare quanto segue.
Sostituibile:
- Funzioni che non usano
this
o arguments
.
- Funzioni utilizzate con
.bind(this)
Non sostituibile:
- Funzioni del costruttore
- Funzione / metodi aggiunti a un prototipo (perché di solito usano
this
)
- Funzioni variabili (se usano
arguments
(vedi sotto))
Diamo un'occhiata più da vicino usando i tuoi esempi:
Funzione di costruzione
Questo non funzionerà perché non è possibile chiamare le funzioni freccia new
. Continuare a utilizzare una dichiarazione / espressione di funzione o utilizzare class
.
Metodi prototipo
Molto probabilmente no, perché i metodi prototipo di solito usano this
per accedere all'istanza. Se non lo usano this
, puoi sostituirlo. Tuttavia, se ti interessa principalmente la sintassi concisa, usa class
con la sua sintassi del metodo conciso:
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
Metodi oggetto
Allo stesso modo per i metodi in un oggetto letterale. Se il metodo desidera fare riferimento all'oggetto stesso tramite this
, continuare a utilizzare le espressioni di funzione o utilizzare la nuova sintassi del metodo:
const obj = {
getName() {
// ...
},
};
callback
Dipende. Dovresti assolutamente sostituirlo se stai aliasando l'esterno this
o stai usando .bind(this)
:
// old
setTimeout(function() {
// ...
}.bind(this), 500);
// new
setTimeout(() => {
// ...
}, 500);
Ma: se il codice che chiama il callback si imposta esplicitamente this
su un valore specifico, come spesso accade con i gestori di eventi, in particolare con jQuery, e il callback utilizza this
(o arguments
), non è possibile utilizzare una funzione freccia!
Funzioni variabili
Poiché le funzioni freccia non hanno le proprie arguments
, non è possibile sostituirle semplicemente con una funzione freccia. Tuttavia, ES2015 introduce un'alternativa all'utilizzo arguments
: il parametro rest .
// old
function sum() {
let args = [].slice.call(arguments);
// ...
}
// new
const sum = (...args) => {
// ...
};
Domanda correlata:
Ulteriori risorse: