Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 34 di 112
  • livello avanzato
Indice lezioni

Arrow function

Cosa sono le Arrow Function, come si dichiarano parametri e valori di ritorno e come viene interpretato al loro interno il significato della keyword this
Cosa sono le Arrow Function, come si dichiarano parametri e valori di ritorno e come viene interpretato al loro interno il significato della keyword this
Link copiato negli appunti

Un nuovo tipo di funzione introdotta dalle specifiche di ECMASCript 2015 è rappresentato dalle arrow function. Si tratta di funzioni anonime con una sintassi molto concisa ed alcune specifiche caratteristiche che analizziamo in questa lezione.

Consideriamo ad esempio una funzione anonima che implementa la somma, come quella che segue:

var somma = function(x, y) {
	return x + y;
};

Possiamo implementarla utilizzando la sintassi delle arrow function nel seguente modo:

var somma = (x, y) => x + y;

Come possiamo vedere, la definizione della funzione è ridotta al minimo: non esiste la parola chiave function, non vengono utilizzate le parentesi graffe per individuare il corpo della funzione e non viene nemmeno utilizzata l'istruzione return.

La sua invocazione è del tutto identica a quella di una funzione anonima assegnata ad una variabile:

var totale = somma(3, 2);

Varianti di Arrow Function

L'esempio che abbiamo appena visto è solo una delle possibili varianti sintattiche di arrow function. È possibile infatti utilizzare delle variazioni in base al numero di parametri ed in base al numero di istruzioni da eseguire all'interno della funzione.

La sintassi generale di una arrow function prevede le parentesi tonde intorno alla lista dei parametri e le parentesi graffe per delimitare il corpo della funzione, come nel seguente esempio:

(x, y) => {return x + y; }

Se il corpo è costituito dalla sola istruzione return che restituisce una espressione, possiamo omettere la parola chiave return e le parentesi graffe, come nell'esempio iniziale:

(x, y) => x + y;

Se la funzione prevede un solo parametro, possiamo omettere le parentesi tonde, come nel seguente esempio:

x => x * 2

Se la funzione non prevede alcun parametro, è obbligatorio l'uso delle parentesi tonde:

() => "Hello world!"

Quando utilizzare le arrow function

Data la sintassi compatta delle arrow function, esse si prestano molto bene ad essere utilizzate come callback. Consideriamo ad esempio il seguente codice:

var numeri = [18, 13, 24]; 
numeri.forEach(function(valore) {
	console.log(valore);
});

Possiamo semplificare la sua sintassi riscrivendolo nel seguente modo:

var numeri = [18, 13, 24]; 
numeri.forEach(valore => console.log(valore));

Abbiamo ridotto ai minimi termini la sintassi della funzione di callback sfruttando la sintassi delle arrow function.

Implicazioni semantiche delle arrow function

Ma le arrow function non introducono soltanto una diversa espressione sintattica nella definizione delle funzioni. Esse hanno anche delle implicazioni semantiche che occorre tener presente per evitare di incappare in situazioni difficili da diagnosticare.

L'aspetto più importante da tener presente è che la parola chiave this all'interno di una arrow function non rappresenta il contesto di esecuzione a runtime come avviene per le funzioni standard. Essa rappresenta sempre lo scope in cui la funzione stessa viene definita.

Proviamo a spiegare questo concetto con un esempio rappresentato dal seguente codice:

var numeri = {
	x: 12,
	y: 3,
	calcola: function(operazione) {
		var fn;
		switch (operazione) {
			case '+':
				fn = function() { return this.x + this.y};
			break;
			case '-':
				fn = function() { return this.x - this.y};
			break;
			default:
				fn = function() {};
		}
		return fn();
	}
} 
numeri.calcola('+');

Abbiamo un oggetto numeri con due proprietà, x e y, che contengono due valori numerici ed un metodo calcola() che consente di effettuare la somma o la differenza tra i due valori in base ad una stringa che rappresenta l'operazione da eseguire.

In coda alla definizione dell'oggetto troviamo l'invocazione del metodo calcola() specificando il simbolo dell'addizione. Il risultato dell'esecuzione del metodo non è, come a prima vista ci aspetteremmo, la somma dei due valori numerici, ma il valore NaN. Il motivo dovrebbe essere abbastanza chiaro: la parola chiave this utilizzata nelle funzioni anonime definite all'interno del metodo calcola() non sta indicando l'oggetto numeri, ma il loro contesto di esecuzione.

Come abbiamo parlato di this e dei contesti di esecuzione, l'approccio classico per aggirare questo problema consiste nel definire una variabile all'interno dello scope del metodo calcola() ed assegnargli il valore di this. Un metodo alternativo consiste nel chiamare le funzioni utilizzando bind().

L'alternativa ad entrambi gli approcci è il ricorso alle arrow function. Possiamo infatti riscrivere il codice precedente come mostrato di seguito per ovviare all'inconveniente:

var numeri = {
	x: 12,
	y: 3,
	calcola: function(operazione) {
		var fn;
		switch (operazione) {
			case '+':
				fn = () => this.x + this.y;
			break;
			case '-':
				fn = () => this.x - this.y
			break;
			default:
				fn = () => {};
		}
		return fn();
	}
} 
numeri.calcola('+');

Con questo approccio abbiamo reso il codice più compatto ed aggirato il problema del contesto di esecuzione, dal momento che in questo caso this rappresenterà il contesto al momento della definizione delle funzioni, e cioè l'oggetto numeri stesso.

Limiti delle arrow function

Le arrow function presentano alcune limitazioni rispetto alle funzioni standard. Ad esempio, esse non possono essere utilizzate per la definizione di metodi di un oggetto. Consideriamo il seguente codice:

var obj = {
	x: 123,
	mostraValoreFunc: function() { console.log(this.x); },
	mostraValoreArrow: () => console.log(this.x)
}; 
obj.mostraValoreFunc()  //123
obj.mostraValoreArrow() //undefined

Mentre il metodo mostraValoreFunc() visualizza il valore corrente della proprietà x di obj, il metodo mostraValoreArrow() visualizza undefined, dal momento che, in questo caso, this non rappresenta l'oggetto obj ma il contesto globale.

Inoltre, le arrow function non possono essere utilizzate come costruttori. Se si prova ad utilizzare una arrow function con l'operatore new otterremo un errore.

Ti consigliamo anche