Come forse saprai, ECMAscript cerca di essere intelligente e inserirà automaticamente il punto e virgola se non li hai scritti esplicitamente. Semplice esempio
function foo() { var bar = 5 return bar }
funzionerà ancora come previsto. Ma ci sono alcuni avvertimenti se ci si basa su questo. Se riscriviamo quella funzione in questo modo
function foo() { var bar = 5 return { bar: bar } }
..che la funzione verrebbe restituita undefined
perché l’interprete inserirà quel punto e virgola subito dopo l’istruzione return
(questa è una ragione per cui si dovrebbe sempre portare parentesi graffe sulla stessa riga di un’istruzione).
Tuttavia, sapendo tutto questo mi chiedo ora quanto è sicura una dichiarazione di return
come la seguente, attraverso i browser e le versioni
function foo() { var a = true, b = true, c = false; return a && b && c; }
Ho appena scritto una return statement
simile in un ambiente di produzione. Solo perché sapevo dei “problemi” con ECMAscript che non erano così intelligenti sull’inserimento di punto e virgola, mi chiedo ora, se quel codice funziona al 100%. Nei miei primi test su FF / Chrome / IE (ultime versioni) questo sembra essere completamente soddisfacente, ma è davvero?
L’ inserimento automatico del punto e virgola “sveglia” se c’è qualcos’altro oltre all’istruzione return
in quella linea? Qualcuno può fornire dettagli a livello di implementazione su questo?
L’interprete / compilatore javascript è così intelligente da inserire solo il punto e virgola automatico se in seguito vi è un Javascript valido.
Il tuo codice funziona, perché && b
così com’è non è un’espressione valida – ecco perché nessun punto e virgola viene inserito dopo il return a
risulta:
return a && b && c;
Però:
return (undefined);//implicitely inserted { .... }
è perfettamente valido e questo è il motivo per cui viene inserito un punto e virgola.
Per completezza il riferimento alla specifica: inserimento automatico del punto e virgola . Vale la pena leggere gli esempi.
Non specifica per browser / implanto, ma la Section 7.9 Automatic Semicolon Insertion
della specifica del linguaggio ECMAScript vale la lettura.
7.9 Inserimento automatico del punto e virgola
Alcune istruzioni ECMAScript (istruzione vuota, istruzione variabile, istruzione espressione, istruzione do-while, istruzione continue, istruzione break, istruzione return e istruzione throw) devono essere terminate con punto e virgola. Tale punto e virgola può sempre apparire esplicitamente nel testo sorgente. Per comodità, tuttavia, tali punti e virgola possono essere omessi dal testo sorgente in determinate situazioni. Queste situazioni sono descritte dicendo che i punti e virgola vengono automaticamente inseriti nel stream di codice del codice sorgente in tali situazioni.
7.9.1 Regole per l’inserimento automatico del punto e virgola Ci sono tre regole base per l’inserimento del punto e virgola:
Quando, mentre il programma viene analizzato da sinistra a destra, viene rilevato un token (chiamato token offendente) non consentito da alcuna produzione della grammatica, quindi viene inserito automaticamente un punto e virgola prima del token offendente se uno o più dei seguenti le condizioni sono vere:
Quando il programma viene analizzato da sinistra a destra, viene rilevata la fine del stream di input dei token e il parser non è in grado di analizzare il stream di token di input come un singolo programma ECMAScript completo, quindi un punto e virgola viene inserito automaticamente alla fine di il stream di input.
Quando, come il programma viene analizzato da sinistra a destra, viene rilevato un token che è consentito da alcune produzioni della grammatica, ma la produzione è una produzione limitata e il token sarebbe il primo token per un terminale o non terminale che segue immediatamente l’annotazione ? [nessun LineTerminator qui]? all’interno della produzione limitata (e quindi tale token è chiamato token limitato) e il token limitato viene separato dal token precedente da almeno un LineTerminator, quindi un punto e virgola viene inserito automaticamente prima del token limitato. Tuttavia, esiste una condizione di override aggiuntiva sulle regole precedenti: un punto e virgola non viene mai inserito automaticamente se il punto e virgola viene analizzato come un’istruzione vuota o se tale punto e virgola diventa uno dei due punti e virgola nell’intestazione di un’istruzione for (vedere 12.6.3). NOTA Le seguenti sono le uniche produzioni limitate nella grammatica: PostfixExpression: LeftHandSideExpression [no LineTerminator qui] ++ LeftHandSideExpression [no LineTerminator qui] – ContinueStatement: continue [no LineTerminator here] Identifier; BreakStatement: break [no LineTerminator here] Identificatore; ReturnStatement: return [no LineTerminator here] Expression; ThrowStatement: lanciare [no LineTerminator qui] Expression; L’effetto pratico di queste produzioni limitate è il seguente: Quando si incontra un token ++ o – dove il parser lo tratta come un operatore postfisso e almeno un LineTerminator si è verificato tra il token precedente e il token ++ o – , quindi un punto e virgola viene inserito automaticamente prima del token ++ o -. Quando viene rilevato un token di continuazione, interruzione, ritorno o lancio e viene rilevato un LineTerminator prima del token successivo, un punto e virgola viene inserito automaticamente dopo il continuare, interrompere, restituire o lanciare token. Il consiglio pratico risultante per i programmatori ECMAScript è: Un operatore postfix ++ o – dovrebbe apparire sulla stessa riga del suo operando. Un’espressione in un’istruzione return o throw dovrebbe iniziare sulla stessa riga del return o throw token. Un identificatore in un’istruzione di interruzione o continuazione deve trovarsi sulla stessa riga dell’interruzione o del token di proseguimento.
7.9.2 Esempi di inserimento automatico del punto e virgola
La fonte
{ 1 2 } 3
non è una frase valida nella grammatica ECMAScript, anche con le regole di inserimento del punto e virgola automatico. Al contrario, la fonte
{ 1 2 } 3
non è anche una frase ECMAScript valida, ma viene trasformata dall’inserimento automatico del punto e virgola nel seguente:
{ 1 ;2 ;} 3;
che è una frase ECMAScript valida. La fonte
for (a; b )
non è una frase ECMAScript valida e non è alterata dall’inserimento automatico del punto e virgola perché il punto e virgola è necessario per l’intestazione dell’istruzione for. L’inserimento automatico del punto e virgola non inserisce mai uno dei due punti e virgola nell’intestazione di un’istruzione for. La fonte
return a + b
viene trasformato dall’inserimento automatico del punto e virgola nel seguente:
return; a + b;
NOTA L’espressione a + b non viene considerata come un valore da restituire dall’istruzione return, poiché un LineTerminator lo separa dal token return. La fonte
a = b ++c
viene trasformato dall’inserimento automatico del punto e virgola nel seguente:
a = b; ++c;
NOTA Il token ++ non è trattato come un operatore postfisso che si applica alla variabile b, poiché si verifica un LineTerminator tra b e ++. La fonte
if (a > b) else c = d
non è una frase ECMAScript valida e non viene alterata dall’inserimento automatico del punto e virgola prima del token else, anche se in quel momento non viene applicata alcuna produzione della grammatica, poiché un punto e virgola inserito automaticamente verrà quindi analizzato come un’istruzione vuota. La fonte
a = b + c (d + e).print()
non viene trasformato dall’inserimento automatico del punto e virgola, perché l’espressione tra parentesi che inizia la seconda riga può essere interpretata come un elenco di argomenti per una chiamata di funzione:
a = b + c(d + e).print()
Nella circostanza che un’istruzione di assegnazione deve iniziare con una parentesi chiusa, è buona norma che il programmatore fornisca un punto e virgola esplicito alla fine dell’istruzione precedente anziché fare affidamento sull’inserimento automatico del punto e virgola.
La tua dichiarazione di reso funzionerà correttamente su tutti i browser, come sottolinea Christoph. Preferisco renderlo ancora più esplicito, se non per i computer, ma per gli umani, almeno ponendo gli operatori e in modo diverso:
return a && b && c;
In questo caso nessuno deve passare un secondo a chiedersi se i semi-colon automatici stiano per causare il caos. Preferisco solo questo per JavaScript, il tuo codice originale è più facile da leggere.