2011-09-20 25 views
38

stavo trafficando con cose diverse, come questoPerché "a + + b" funziona, ma "a ++ b" no?

var a = 1, b = 2; 
alert(a + - + - + - + - + - + - + - + b); //alerts -1 

e ho potuto rimuovere gli spazi, e sarebbe ancora funzionare.

a+-+-+-+-+-+-+-+b 

Poi ho provato

a + + b 

Correva e valutata a 3, ma quando ho rimosso gli spazi, (a++b) sarebbe non correre, e aveva un avvertimento che diceva "plus Confondere ".

posso capire che in casi come

a+++++b 

che potrebbe essere interpretata come una delle caratteristiche seguenti

(a++) + (++b) 
(a++) + +(+b) 
a + +(+(++b)) 
a + +(+(+(+b))) 

che sarebbe confusione.

Ma nel caso di

a++b 

l'unico modo valido per interpretare questo, per quanto posso dire, è

a + +b 

Perché non a++b lavoro?

+8

Immagino che sia in conflitto con un ++ che è valido synax, o ++ b. – TheCodeKing

+3

Potrebbe anche essere interpretato (a ++) b o a (++ b) ... –

+0

'++ b' è valido anche – Andrew

risposta

57

Il parser Javascript è avido (che corrisponda l'operatore valida più lunga ogni volta), quindi diventa l'operatore ++ da a++b, rendendo:

(a++) b 

che non è valido. Quando si mette in spazi a + + b, il parser interpreta in questo modo:

(a) + (+b) 

che è valido e funziona a essere tre.

Vedere questo articolo di Wikipedia su Maximal munch per ulteriori dettagli.

+7

Penso che questa sia la risposta chiave: parser è ** avido **. – Andrey

+3

Se non fosse avido, sarebbe piuttosto inutile. 'a ++' sarebbe interpretato come 'a + +', che è illegale. Una delle intuizioni importanti è che capire quali sono i token dell'input viene prima di capire cosa significano quei token. Quindi '++' diventerà il token '++' anche se quel token non è valido in quel contesto. –

12

Sta leggendo a++, quindi incontra uno b e non sa cosa fare con esso.

+3

+1 per il massimo munch! –

+0

@carlnorum sì. –

7

Questo è b/c della differenza tra gli operatori unari.

"a + + b" is the same as "a + (+b)" 
"a++b" is the same as "(a++) _ b" <--- there is a missing operator where the _ is 
3

Le regole di precendenza dell'operatore di Javascript per l'operatore di incremento ++ non hanno un'associatività di sinistra. Ciò significa che a++b può essere interpretato come a++ b o a ++b a seconda dell'implementazione particolare. Ad ogni modo, si tratta di un errore di sintassi, in quanto hai 2 variabili, un operatore unario e niente che unisce le due variabili.

In termini pratici:

a = 1 
b = 2; 

a++ b; -> 2 2 
a ++b; -> 1 3 

Che cosa vuol dire 1 3 come codice JS?

3

La maggior parte dei parser di linguaggio di programmazione tentativi per ottenere più lunga porzione di testo che abbia senso, in modo che quando Javascript vede:

[a][][][][] 

"variabile un" - ha senso, vediamo carattere successivo:

[a][+][][] 

"sarà l'aggiunta di un varaible" - ha senso, vediamo carattere successivo:

[a][+][+][] 

"posterò-incremento variabile a" - ha senso, vediamo carattere successivo,

[a][+][+][b] 

Questo non ha senso. Ho due espressioni (a ++) e (b) e nessun operatore infisso tra di loro.

Se lo si rende a+ +b, non troverà l'operatore ++ e funzionerà come a + + b.

1

Longest Match regola entra in figura qui. Dice che il parser deve prendere in considerazione il token più lungo partendo da sinistra a destra (presumo che la grammatica di Javascript sia da sinistra a destra). Quindi applica questa regola e otterrai la tua risposta.

Il parser si avvierà da sinistra e creerà un to, +, + & b token separati in caso di "a + + b" (a causa dello spazio bianco tra di essi). Nel caso di "a ++ b" applicherà la regola di corrispondenza più lunga e creerà un + & b come token. a ++ b come espressione non ha alcun senso semantico, quindi non sarà compilato.

0

La risposta è che ++ è un operatore e +, e che + + è due operatori +, non un operatore ++.

Sebbene non sia Javascript, C++ si diverte molto con gli operatori + e ++. Questo è stato studiato in uno dei Gurus of the Week da lontano quando.

Problemi correlati