2012-10-05 11 views
13

Come probabilmente saprai, ECMAscript cerca di essere intelligente e inserirà automaticamente punti e virgola se non li hai scritti esplicitamente. Esempio sempliceInserimento e ritorno automatico dei punti e virgola

function foo() { 
    var bar = 5 

    return bar 
} 

continuerà a funzionare come previsto. Ma ci sono alcuni avvertimenti se ci si basa su questo. Se abbiamo ri-scrivere che la funzione in questo modo

function foo() { 
    var bar = 5 

    return 
    { 
     bar: bar 
    } 
} 

..che funzione sarebbe ora tornare undefined perché l'interprete sarebbe inserire tale punto e virgola dopo la dichiarazione return (che è un motivo per cui si dovrebbe portare sempre parentesi graffe sulla stessa linea come una dichiarazione).

Tuttavia, sapendo tutto questo mi chiedo ora come sicuro una dichiarazione return come il seguente è, tutti i browser e le versioni

function foo() { 
    var a = true, 
     b = true, 
     c = false; 

    return a 
      && b 
      && c; 
} 

ho appena scritto un simile return statement 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 di punto e virgola "sveglia" se c'è qualcos'altro oltre all'istruzione return in tale riga? Qualcuno può fornire dettagli a livello di implementazione su questo?

+1

duplicato possibilmente migliore: [Perché i risultati variano in base al posizionamento delle parentesi graffe?] (Http://stackoverflow.com/q/3641519/1048572) – Bergi

risposta

10

L'interprete/compilatore javascript è così intelligente da inserire solo il punto e virgola automatico se in seguito è presente Javascript valido.

Il tuo codice funziona, perché && b così com'è non è espressione valida - è per questo che nessun punto e virgola viene inserito dopo il return a conseguente:

return a && b && c; 

Tuttavia:

return (undefined);//implicitely inserted 
{ 
    .... 
} 

è perfettamente valido e ecco perché viene inserito un punto e virgola.

Per completezza, riferimento alle specifiche: automatic semicolon insertion. Vale la pena leggere gli esempi.

+0

Grazie per la risposta: ho già trovato quella sezione delle specifiche, tuttavia, mi sto ancora chiedendo quanto è buono/corretto quella particolare sezione è stata implementata per i browser (mobili) e le versioni e se possiamo contare al 100% su tale comportamento. – jAndy

+0

Ci sono alcuni piccoli Browser per dispositivi mobili che supportano solo un sottoinsieme limitato di ecmascript, ma queste sono per lo più funzioni speciali. Tuttavia, sono abbastanza fiducioso che queste parti "di base" delle specifiche siano implementate in modo abbastanza coerente attraverso i browser. – Christoph

+1

Almeno in Chrome, la richiesta * L'interprete/compilatore javascript è così intelligente da inserire solo il punto e virgola automatico se in seguito è presente Javascript valido. * È falso. Ad esempio, prendi l'esempio dell'OP e avvolgi la chiave 'bar' tra virgolette in modo che legga' 'bar''. Ora, con il tutore aperto sulla stessa linea del ritorno, tutto funziona; con l'interruzione di linea inserita tra loro, l'inserimento automatico del punto e virgola crea un errore di sintassi. –

0

La dichiarazione di reso funzionerà correttamente su tutti i browser, come sottolinea Christoph. Io preferisco per rendere ancora più esplicito, se non per i computer, ma per gli esseri umani, almeno mettendo il e gli operatori in modo diverso:

return a && 
     b && 
     c; 

In questo caso nessuno ha bisogno di spendere un secondo chiedendosi se automatiche e virgola sono andando a devastare. Preferisco solo questo per JavaScript, il tuo codice originale è più facile da leggere.

2

Non specifico del browser/dell'installazione, ma Section 7.9 Automatic Semicolon Insertion dello ECMAScript Language Specification vale la pena leggere.

7.9 automatico e virgola inserimento

Alcune dichiarazioni ECMAScript (istruzione vuota, economico variabile, istruzione di espressione, do-while dichiarazione, istruzione continue, istruzione break, istruzione return, e gettare dichiarazione) deve essere terminato con un 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 vengono descritte dicendo che i punti e virgola vengono automaticamente inseriti nel flusso di codice sorgente in tali situazioni.

7.9.1 Regolamento automatico e virgola Inserimento Ci sono tre regole fondamentali di inserimento e virgola:

  1. Quando, come il programma viene analizzato da sinistra a destra, un gettone (chiamato token incriminata) è incontra un non è consentito da qualsiasi produzione della grammatica, poi una virgola viene inserito automaticamente prima del token offendere se uno o più delle seguenti condizioni:

    • L'offe nding token è separato dal token precedente da almeno un LineTerminator.
    • Il token incriminato è}.
  2. Quando, come il programma viene analizzato da sinistra a destra, alla fine del flusso di ingresso di token si incontra e il parser è in grado di analizzare il flusso di token di input come una singola completo programma ECMAScript, quindi un punto e virgola viene inserito automaticamente alla fine del flusso di input.

  3. Quando, come il programma viene analizzato da sinistra a destra, si incontra un token che è consentito da alcuni la produzione della grammatica, ma la produzione è una produzione limitata e il token sarebbe la prima token per un terminale o non terminale che segue immediatamente l'annotazione? [nessun LineTerminator qui]? all'interno della produzione limitata di (e quindi tale token è denominato token limitato) e il token limitato è separato dal token precedente da almeno un LineTerminator, quindi un punto e virgola viene automaticamente inserito prima del token con restrizioni. 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 a dichiarazione (vedi 12.6.3). NOTA Le seguenti sono le uniche produzioni soggette a restrizioni della grammatica: PostfixExpression: LeftHandSideExpression [no LineTerminator qui] ++ LeftHandSideExpression [no LineTerminator qui] - ContinueStatement: continuano [no LineTerminator qui] Identifier; BreakStatement: interruzione [no LineTerminator qui] Identificatore; ReturnStatement: return [no LineTerminator here] Espressione; ThrowStatement: throw [no LineTerminator here] Espressione; L'effetto pratico di queste produzioni limitate è il seguente: Quando si incontra un token ++ o - dove il parser lo considera come un operatore postfisso e almeno uno LineTerminator si è verificato tra il token precedente e il ++ o - token, quindi un punto e virgola viene automaticamente inserito prima del token ++ o -. Quando si incontra un token di continuazione, interruzione, ritorno o lancio e un LineTerminator viene rilevato 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 deve iniziare sulla stessa riga del token return o throw. 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 Automatica e virgola Inserimento

La fonte

{ 1 2 } 3 

non è una frase valida nella grammatica ECMAScript, anche con le regole automatiche di inserimento e virgola. In contrario, la fonte

{ 1 
2 } 3 

non è anche una frase ECMAScript valida, ma viene trasformato mediante inserimento virgola automatica nel seguente:

{ 1 
;2 ;} 3; 

che è una frase ECMAScript valido. La fonte

for (a; b 
) 

non è una frase ECMAScript valido e non è alterata mediante inserimento automatico virgola perché il virgola è necessaria per l'intestazione di una for. L'inserimento automatico del punto e virgola non inserisce mai uno dei due punti e virgola nell'intestazione dell'istruzione for per . La fonte

return 
a + b 

viene trasformato mediante inserimento automatico virgola nelle seguenti:

return; 
a + b; 

NOTA L'espressione a + b non è trattato come un valore da restituire dall'istruzione ritorno, perché un LineTerminator lo separa dal ritorno del token. La fonte

a = b 
++c 

viene trasformato mediante inserimento automatico virgola nelle seguenti:

a = b; 
++c; 

NOTA Il token ++ non è trattato come un operatore postfisso applicando alla variabile b, poiché si verifica un LineTerminator tra b e ++. La fonte

if (a > b) 
else c = d 

non è una frase ECMAScript valido e non è alterata mediante inserimento automatico virgola prima else gettone, anche se nessuna produzione della grammatica applica a quel punto, perché una virgola inserito automaticamente sarebbe poi essere analizzato come una dichiarazione vuota. La fonte

a = b + c 
(d + e).print() 

non viene trasformato mediante inserimento automatico virgola, perché l'espressione parentesi, che inizia la seconda linea può essere interpretato come una lista di argomenti per una chiamata di funzione:

a = b + c(d + e).print() 

Nella circostanza che una dichiarazione di assegnazione deve iniziare con una parentesi chiusa, è una buona idea per il programmatore fornire un punto e virgola esplicito alla fine dell'istruzione precedente piuttosto che fare affidamento sull'inserimento automatico del punto e virgola di .

Problemi correlati