W3docs

Oggetto Function di JavaScript ed Espressioni di Funzione con Nome (NFE)

Le funzioni JavaScript sono object: leggi le proprietà name e length, aggiungi proprietà personalizzate e usa le Named Function Expression (NFE) per la ricorsione.

Le funzioni sono object

In JavaScript, ogni funzione è un object. Questo singolo fatto spiega molti comportamenti che altrimenti sembrerebbero magia: puoi passare una funzione come qualsiasi valore, memorizzarla in una variabile, leggere proprietà da essa e persino aggiungere le tue proprietà.

Crei già funzioni continuamente con dichiarazioni ed espressioni di funzione. Questo capitolo analizza cos'è una funzione una volta creata: un object con utili proprietà built-in (name e length), la capacità di contenere proprietà personalizzate e una forma speciale — la Named Function Expression — che consente a una funzione di riferirsi a se stessa in modo affidabile.

Questa pagina presuppone che tu abbia familiarità con le Function Expression. Se let f = function() {...} è una novità per te, leggila prima.

La proprietà name

Ogni funzione ha una proprietà name che contiene il nome della funzione come string. La parte interessante è che JavaScript la compila anche quando non c'è un nome nel punto ovvio — un comportamento chiamato denominazione contestuale.

javascript— editable

Il motore guarda l'assegnazione e copia il nome della variabile sulla funzione anonima. Questo funziona anche per i parametri predefiniti e i metodi degli object:

javascript— editable

Non c'è magia che funzioni sempre, però. Se non c'è un nome e nulla da cui copiarne uno — ad esempio una funzione creata all'interno di un array — name è una string vuota:

javascript— editable

La proprietà name è utile per il logging e il debugging: una stack trace che dice at sayHi è molto più utile di at <anonymous>.

La proprietà length

La proprietà length di una funzione restituisce il numero di parametri dichiarati nella sua definizione. I parametri rest (...rest) e i parametri con valori predefiniti non vengono contati, e il conteggio si interrompe al primo di tali parametri.

javascript— editable

Un utilizzo comune di length è quello di esaminare una callback. Alcune librerie chiamano un handler in modo diverso a seconda di quanti argomenti si aspetta — ad esempio, trattando un handler senza argomenti come "esegui una volta per tutti" e un handler con un argomento come "esegui una volta per elemento".

Proprietà personalizzate

Poiché una funzione è un object, puoi aggiungervi le tue proprietà. Questo è diverso da una variabile locale: una proprietà vive sulla funzione e sopravvive tra una chiamata e l'altra, quindi è un modo ordinato per dare a una funzione il proprio stato persistente.

Un esempio classico è un contatore di chiamate:

javascript— editable

Una proprietà di funzione non è la stessa cosa di una variabile all'interno della funzione. Una variabile locale si azzera ad ogni chiamata; una proprietà persiste, ed è anche leggibile e scrivibile dall'esterno, il che la rende utile per la configurazione (ad esempio per memorizzare i risultati nella cache direttamente sulla funzione).

Named Function Expression (NFE)

Una Named Function Expression è un'espressione di funzione che porta un nome dopo la parola chiave function:

let sayHi = function func(who) {
  console.log("Hello, " + who);
};

Questo sembra insolito — perché dare un nome a qualcosa già assegnato a sayHi? Il nome func qui è speciale in due modi:

  • Consente alla funzione di riferirsi a se stessa in modo affidabile dall'interno del proprio corpo.
  • È visibile solo all'interno della funzione — non puoi chiamare func() dall'esterno.

Perché il nome interno è importante

Potresti pensare di poter usare semplicemente la variabile esterna sayHi per il riferimento a se stessa. Il problema è che la variabile esterna può cambiare. Con una NFE, il nome interno punta sempre alla funzione corrente, indipendentemente da cosa accade alla variabile:

javascript— editable

Se la funzione avesse chiamato sayHi("Guest") invece di func("Guest"), la chiamata avrebbe generato un TypeError perché sayHi era stato impostato a null. Il nome interno è immune a questo problema.

NFE e ricorsione

Questo auto-riferimento è esattamente ciò di cui ha bisogno la ricorsione. Una NFE mantiene funzionante una chiamata ricorsiva anche se la funzione viene successivamente riassegnata o passata sotto un altro nome — vedi Ricorsione e Stack JavaScript per il quadro completo.

javascript— editable

Nota che il trucco del nome interno si applica solo alle Expression di funzione. Una Function Declaration non può avere un nome interno separato, e non ha modo di nascondere un nome dall'ambito esterno, quindi non può mantenere un auto-riferimento privato allo stesso modo.

Quando usare queste funzionalità

  • Usa name per log e output di debugging più chiari.
  • Usa length quando scrivi librerie che si adattano all'arità di una callback.
  • Usa proprietà personalizzate per dare a una funzione uno stato persistente (contatori, cache, configurazione) senza una closure circostante o una variabile globale.
  • Usa una Named Function Expression ogni volta che un'espressione di funzione deve chiamare se stessa — specialmente per la ricorsione o gli handler rimovibili — in modo che la chiamata sopravviva alla riassegnazione della variabile.

Una funzione JavaScript è un object che puoi ispezionare ed estendere. La proprietà name fornisce il suo nome (spesso compilato in modo contestuale), length riporta il numero di parametri dichiarati e puoi aggiungere proprietà personalizzate per uno stato persistente. Una Named Function Expression aggiunge un nome solo interno che consente a una funzione di chiamare se stessa in modo affidabile, che è il modo più sicuro per scrivere espressioni di funzione auto-referenziali e ricorsive.

Esercitazione

Pratica
Cos'è una NFE (Named Function Expression) in JavaScript?
Cos'è una NFE (Named Function Expression) in JavaScript?
Was this page helpful?