Sintassi di chiamata di funzione immediata


110

C'è un'opzione JSLint , una delle parti buone in effetti, che "[richiede] parentesi intorno a invocazioni immediate", il che significa che la costruzione

(function () {

  // ...

})();

dovrebbe invece essere scritto come

(function () {

  // ...

}());

La mia domanda è questa: qualcuno può spiegare perché questa seconda forma potrebbe essere considerata migliore? È più resiliente? Meno soggetto a errori? Che vantaggio ha rispetto alla prima forma?


Da quando ho posto questa domanda, ho capito l'importanza di avere una chiara distinzione visiva tra i valori delle funzioni e i valori delle funzioni. Considera il caso in cui il risultato dell'invocazione immediata è il lato destro di un'espressione di assegnazione:

var someVar = (function () {

  // ...

}());

Sebbene le parentesi più esterne siano sintatticamente non necessarie, la parentesi di apertura fornisce un'indicazione in primo piano che il valore assegnato non è la funzione stessa ma piuttosto il risultato della funzione invocata.

Questo è simile al consiglio di Crockford in merito alla capitalizzazione delle funzioni del costruttore: è pensato per servire come indizio visivo per chiunque guardi il codice sorgente.


Grazie per averlo fatto notare. Non ho mai trovato un modo per sbarazzarmi del messaggio di avviso di JSLint "Fai attenzione quando crei funzioni all'interno di un ciclo". Sono stato attento e ho chiuso la funzione, ma JSLint si è ancora lamentato. Ora so che si presume che abbia usato il secondo pattern.
viam0Zah


L'ho fatto "sbagliato" per tutto questo tempo. E quando dico "tutto questo tempo", scrivo JavaScript dal 1995.
Dave Land,

Risposte:


73

Dalla guida alle convenzioni di stile di Douglass Crockford : (cerca "invocato immediatamente")

Quando una funzione deve essere invocata immediatamente, l'intera espressione di chiamata deve essere racchiusa tra parentesi in modo che sia chiaro che il valore prodotto è il risultato della funzione e non la funzione stessa.

Quindi, fondamentalmente, ritiene che renda più chiara la distinzione tra i valori delle funzioni e i valori delle funzioni. Quindi, è una questione stilistica, non proprio una differenza sostanziale nel codice stesso.

riferimento aggiornato, il vecchio PPT non esiste più


1
Sono contento di aver letto questo. Ho appena finito di leggere Javascript: The Good Parts, e quello che continuavo a pensare era che assegnare il risultato della chiamata a una funzione è una sintassi davvero pessima, perché devi guardare la prima e l'ultima riga per capire cosa sta succedendo. Non usa le parentesi avvolgenti nel libro, ma capisco esattamente perché le consiglia.
Skilldrick

2
@altCognito, puoi fornire un nuovo collegamento per il PPT?
th1rdey3

1
Ho cercato sul web, ma non riesco ancora a trovare una copia di quel PPT
Forethinker

1
Non sono riuscito a trovare il PPT originale, ma sono stato in grado di trovare lo stesso punto trovato nella sua guida alle convenzioni javascript.
cgp

archive.org ce l'hai?
John Greene

2

Le funzioni anonime chiamate immediatamente vengono racchiuse tra parentesi perché:

  1. Sono espressioni di funzione e tralasciando le parentesi verrebbe interpretato come una dichiarazione di funzione che è un errore di sintassi.

  2. Le espressioni di funzione non possono iniziare con la parola funzione.

  3. Quando si assegna l'espressione di funzione a una variabile, la funzione stessa non viene restituita, viene restituito il valore di ritorno della funzione, quindi i genitori valutano cosa c'è dentro e producono un valore.quando la funzione viene eseguita e le parentesi finali fanno ..}()sì che la funzione venga eseguita immediatamente.


Dathan, stai rispondendo a una domanda diversa. Hai ragione sul fatto che le parentesi che lo racchiudono sono talvolta sintatticamente necessarie in modo che il parser possa distinguere le espressioni di funzione dalle dichiarazioni di funzione. Ma la mia domanda riguarda il posizionamento delle parentesi di invocazione. Il tuo terzo punto è impreciso; le parentesi che la racchiudono non sono necessarie in questo caso.
Bobby Eickhoff

Stavo rispondendo al tuo primo esempio in cui la funzione anonima chiamata immediatamente non era assegnata a una variabile e quindi le parentesi sono sintatticamente necessarie per i primi 2 motivi. Il terzo motivo è stato semplicemente ripristinare ciò che hai detto: "la parentesi di apertura fornisce un'indicazione in primo piano che il valore assegnato non è la funzione stessa ma piuttosto il risultato della funzione invocata". Ma immagino non fosse chiaro.
Dathan

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.