Funzione freccia / dichiarazione di funzione / espressioni: sono equivalenti / scambiabili?

Domanda canonica Se trovi una domanda sui problemi dopo aver sostituito una dichiarazione / espressione di funzione con una funzione freccia, chiudila come duplicata di questa.

Le funzioni freccia in ES2015 forniscono una syntax più concisa. Posso sostituire tutte le mie dichiarazioni / espressioni di funzione con le funzioni freccia ora? Cosa devo cercare?

Esempi:

Funzione del costruttore

function User(name) { this.name = name; } // vs const User = name => { this.name = name; }; 

Metodi prototipo

 User.prototype.getName = function() { return this.name; }; // vs User.prototype.getName = () => this.name; 

Metodi object (letterale)

 const obj = { getName: function() { // ... } }; // vs const obj = { getName: () => { // ... } }; 

callback

 setTimeout(function() { // ... }, 500); // vs setTimeout(() => { // ... }, 500); 

Funzioni variabili

 function sum() { let args = [].slice(arguments); // ... } // vs const sum = () => { let args = [].slice(arguments); // ... }; 

tl; dr: No! Le funzioni freccia e le dichiarazioni / espressioni di funzioni non sono equivalenti e non possono essere sostituite alla cieca.
Se la funzione che vuoi sostituire non usa this , arguments e non viene chiamata con new , allora sì.


Come così spesso: dipende . Le funzioni delle frecce hanno un comportamento diverso rispetto alle dichiarazioni / espressioni di funzione, quindi prima diamo un’occhiata alle differenze:

1. Lessico this e arguments

Le funzioni freccia non hanno il proprio arguments o arguments vincolante. Invece, quegli identificatori sono risolti nello scope lessicale come qualsiasi altra variabile. Ciò significa che all’interno di una funzione di freccia, this e gli arguments riferiscono ai valori di this e agli arguments nell’ambiente in cui è definita la funzione di freccia (cioè “all’esterno” della funzione di 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 

Guarda questo esempio di Plnkr

La variabile è molto diversa. timesCalled incrementi di timesCalled solo di 1 ogni volta che viene chiamato il pulsante. Quale risponde alla mia domanda personale:

.click( () => { } )

e

.click(function() { })

entrambi creano lo stesso numero di funzioni quando vengono usate in un ciclo, come si può vedere dal conteggio Guid nel Plnkr.