Espressioni di funzione

Le espressioni di funzioni sono funzioni create dove è prevista un'espressione. Incontrerai spesso espressioni di funzione come valori assegnati a una variabile. Sebbene una dichiarazione di funzione richieda sempre un nome, puoi utilizzare espressioni di funzione per creare funzioni anonime per omettere l'identificatore e seguire la parola chiave function con una coppia di parentesi contenenti parametri facoltativi:

const myVariable = function() { };

Puoi quindi chiamare le espressioni di funzione utilizzando l'identificatore della variabile:

const myVariable = function() {
    console.log( "This is my function." );
};

myVariable();
> "This is my function."

Puoi anche utilizzare espressioni di funzione per creare funzioni con nome che utilizzano una sintassi simile alle dichiarazioni delle funzioni:

const myVariable = function myFunction() {
    console.log( "This is my function." );
};

myVariable();
> "This is my function."

Tuttavia, a differenza delle dichiarazioni di funzione, è possibile accedere a un'espressione di funzione con nome tramite il nome della funzione solo all'interno della funzione stessa:

const myVariable = function myFunction() {
  console.log( `I'm a ${ typeof myFunction }.`);
};

typeof myFunction;
> "undefined"

typeof myVariable;
> "function"

myVariable();
> "I'm a function."

I nomi associati alle espressioni di funzione sono utili principalmente per il debug. Un'espressione di funzione con nome può anche chiamarsi in modo ricorsivo, anche se questo non è un caso d'uso molto comune nello sviluppo moderno:

const myVariable = function myFunction() {
    console.log( "One second elapsed." );
    setTimeout( myFunction, 1000 );
};

setTimeout( myVariable, 1000 );
> "One second elapsed."
> "One second elapsed."
> "One second elapsed."
…

Espressioni di funzioni freccia

Le espressioni di funzioni freccia (spesso chiamate "funzioni freccia" o, raramente, "funzioni lambda") sono state introdotte in ES6 per fornire una sintassi concisa per la creazione di espressioni di funzione anonime con alcuni comportamenti unici.

Puoi creare una funzione freccia dove è prevista un'espressione, ad esempio come valore assegnato a una variabile. Nella sua forma più comune, una funzione freccia è composta da una coppia di parentesi corrispondenti contenenti zero o più parametri, una freccia costituita da un singolo segno di uguale e un carattere maggiore di (=>) e da una coppia di parentesi graffe corrispondenti contenenti il corpo della funzione:

const myFunction = () => {};

In determinate condizioni, è possibile rendere la sintassi ancora più compatta. Se utilizzi un solo parametro, puoi omettere le parentesi iniziali:

const myFunction = myParameter => {};

Quando vuoi che il corpo della funzione restituisca il valore di una singola espressione, non è necessario racchiuderlo tra parentesi graffe né la parola chiave return:

const myFunction = () => 2 + 2

myFunction()
> 4

Le funzioni a freccia sono univoche in quanto non hanno un proprio contesto per i valori arguments o this. Ereditano entrambi i valori dall'ambiente di aggregazione lessicalmente della funzione freccia, la funzione di inclusione più vicina che fornisce quei contesti.

function myParentFunction() {
    this.myProperty = true;
    let myFunction = () => {
            console.log( this );
    }
    myFunction();
};

let myInstance = new myParentFunction();
> Object { myProperty: true }

Richiama funzioni freccia

Le funzioni a freccia non associano gli argomenti allo stesso modo degli altri tipi di funzioni. Un oggetto arguments nel corpo di una funzione freccia eredita il valore dall'ambiente di aggregazione più vicina della funzione freccia:

function myFunction() {
    let myArrowFunction = () => {
            console.log( arguments[ 0 ] );
    }
    myArrowFunction( true );
};

myFunction( false );
> false

In questo esempio, una funzione esterna chiamata con l'argomento false chiama una funzione di freccia interna con l'argomento true. Poiché l'oggetto arguments all'interno della funzione freccia si risolve nell'associazione nella funzione esterna, la funzione interna registra il valore false della funzione esterna.

Se non esiste alcun oggetto arguments da ereditare dal contesto padre, l'oggetto arguments della funzione freccia non è definito e il tentativo di accedervi provoca un errore:

let myArrowFunction = () => {
    console.log(arguments);
};
myArrowFunction( true );
> Uncaught ReferenceError: arguments is not defined

Espressioni di funzione immediatamente richiamate (IIFE)

Un'espressione di funzione immediatamente richiamata (IIFE), a volte chiamata anche "funzione anonima a esecuzione automatica", è un'espressione di funzione che viene chiamata immediatamente quando viene definita. Un IIFE utilizza un'espressione di funzione creata racchiudendo la funzione in un operatore di raggruppamento. Una seconda coppia di parentesi corrispondente chiama quindi la funzione, subito dopo la definizione della funzione stessa o immediatamente dopo l'operatore di raggruppamento. Se utilizzi una funzione standard, non c'è alcuna differenza pratica tra i due approcci:

(function() {
    console.log( "IIFE.")
    }
)();
> "IIFE."

(function() {
    console.log( "IIFE.")
    }
());
> "IIFE."

Il primo esempio chiama l'espressione della funzione raggruppata. Il secondo esempio chiama una dichiarazione di funzione all'interno degli operatori di raggruppamento e il risultato finale viene quindi valutato come espressione raggruppata. Il risultato è lo stesso in entrambi i casi.

Tuttavia, c'è una differenza quando il tuo IIFE è una funzione a freccia. In questo caso, le parentesi utilizzate per chiamare la funzione devono essere esterne agli operatori di raggruppamento, poiché una funzione a freccia da sola non è un'espressione, ma deve essere creata in un contesto in cui è prevista un'espressione. Provare a chiamare la funzione freccia dall'interno dell'ambito degli operatori di raggruppamento significherebbe chiamare una funzione freccia che non è ancora stata creata nel contesto di un'espressione:

( () => {
    console.log( "IIFE." );
}() );
> Uncaught SyntaxError: missing ) in parenthetical

Poiché gli operatori di raggruppamento si aspettano un'espressione, viene definita la funzione freccia al loro interno, consentendo alle parentesi che li seguono di chiamare l'espressione raggruppata:

( () => {
    console.log( "IIFE." );
} )();
> "IIFE."

Applicazioni legacy, utilizzavano spesso IIFE per gestire l'ambito, in particolare per evitare di contaminare l'ambito globale con variabili basate sulle funzioni e dichiarazioni di funzioni. Prima dell'introduzione della definizione dell'ambito dei blocchi in ES6, era pratica comune avvolgere un'intero script in un IIFE per evitare l'inquinamento accidentale dell'ambito globale.

Verifica le tue conoscenze

Puoi chiamare un'espressione di funzione con nome in base al nome al di fuori della funzione?

No