L'assegnazione con una virgola funziona?


108

Perché aaa = 1,2,3funziona e imposta il valore di aaaa 1?

Perché non var bbb = 1,2,3funziona?

Perché var bbb = (1,2,3)funziona e imposta il valore di bbba 3?

Esempio di sessione della console


9
Viene visualizzato un errore di sintassi perché i nomi delle variabili non possono iniziare con un numero. var a1,a2,a3;dichiarerà semplicemente tre variabili locali.
Jared Farrish

Risposte:


200

C'è molto da fare qui, ma fondamentalmente si tratta dell'operatore virgola .

L'operatore virgola valuta entrambi i suoi operandi (da sinistra a destra) e restituisce il valore del secondo operando.


Questo codice:

aaa = 1,2,3

È equivalente a:

aaa = 1;
2;
3;

Quindi aaaviene implicitamente dichiarato e assegnato un valore di 1. Si noti che l'output sulla console è il risultato dell'ultima istruzione, 3.


Questo codice:

var bbb = 1,2,3

È un errore di sintassi perché le virgole nelle dichiarazioni di variabili vengono utilizzate per dichiarare più variabili in una singola riga. Come sottolinea l'articolo di MDN,

Notare che la virgola varnell'istruzione non è l'operatore virgola, perché non esiste all'interno di un'espressione. Piuttosto, è un carattere speciale nelle varaffermazioni combinarne più in una.

Quindi questo codice è più o meno equivalente a:

var bbb = 1;
var 2;
var 3;

Ovviamente 2non è un identificatore valido, quindi a quel punto fallisce.


Questo codice:

var bbb = (1,2,3)

È molto simile al primo, tranne perché i valori numerici sono racchiusi tra parentesi, vengono valutati per primi. Quindi questo è approssimativamente equivalente a:

1;
2;
var bbb = 3;

17
Inoltre, =in var bbb = 1;non è la stessa =di in aaa = 1;- provengono da produzioni diverse (Initialiser vs AssignmentExpression) nella grammatica e capita semplicemente di utilizzare lo stesso token.
Ryan Cavanaugh

7
Spiegazione molto bella. Ciò che non era del tutto esplicito era che a = 1, 2, 3può essere tra parentesi come (a = 1), 2, 3che valuta come a = 1; 2; 3(e restituisce 3, ad esempio b = (a = 1, 2, 3)assegnerebbe 3 a b). Al contrario, a = (1, 2, 3)valuta come 1; 2; a = 3e restituisce 3.
CompuChip

Cosa dice l'MDN sui genitori nell'assegnazione di variabili e perché è al contrario? Non sono riuscito a trovare il documento
Brian il

@staticx Niente è veramente fatto "al contrario". Le parentesi vengono valutate per prime. Proprio come quando hai (1 + 2) * 3, 1 + 2viene valutato per primo e il risultato di quell'espressione viene sostituito di nuovo nell'espressione esterna per il resto della valutazione.
pswg

9

La virgola ha molteplici usi in Javascript. Nell'espressione:

a = 1, 2, 3;

è un operatore che restituisce semplicemente il suo argomento di destra. Ma fa anche parte della sintassi delle vardichiarazioni, che sono:

var var1 [ = val1 ], var2 [ = val2 ], var3 [ = val3 ], ...;

(dove [...]significa che la parte è facoltativa). Nella tua vardichiarazione mancano i nomi delle variabili dopo le virgole, quindi non viene analizzata. Potresti ottenere l'effetto che desideri con:

var a = (1, 2, 3);

Le parentesi costringono le virgole a essere trattate come operatori anziché come delimitatori tra le dichiarazioni di variabili.


7

Nei tuoi esempi, la virgola viene utilizzata in due contesti:

var dichiarazione

La sintassi vardell'istruzione è:

var varname1 [= value1 [, varname2 [, varname3 ... [, varnameN]]]];

Qui, la virgola viene utilizzata per separare le coppie nome-valore delle variabili. Quanto segue non funzionerà perché il nome di una variabile non può iniziare con una cifra (vedere i nomi degli identificatori ):

var bbb = 1, 2, 3;
// SyntaxError: Unexpected number

Operatore virgola

L'operatore virgola valuta entrambi i suoi operandi (da sinistra a destra) e restituisce il valore del secondo operando. Le seguenti espressioni funzionano come segue:

aaa = 1, 2, 3;
  • aaa = 1, 2 produce 2
    • nota che aaa = 1viene valutato per primo perché =ha una priorità maggiore di,
  • 2, 3 produce 3
var bbb = (1, 2, 3);
  • l'espressione (1, 2, 3)produce 3come descritto sopra
  • Alla variabile bbbviene assegnato il valore3

2
aaa = 1, 2, 3=> L'operatore virgola viene utilizzato per separare i seguenti 3 affermazioni: aaa=1, 2e 3. Il risultato dell'operatore virgola è il valore dell'ultima istruzione 3. Tuttavia, aaa viene assegnato il valore 1, come si può chiaramente vedere dallo screenshot dell'OP. La ragione di ciò è la precedenza dell'operatore, con l'operatore virgola che ha la precedenza più bassa.
Tibos

1

Nel primo caso:

aaa = 1,2,3

le virgole servono come separatori di espressioni. Esegue un'assegnazione a aaa, quindi lo calcola 2e lo scarta, quindi lo calcola 3e lo scarta.

Nel secondo:

var bbb = 1,2,3

La varparola chiave dice al compilatore Javascript che la cosa successiva dopo a ,dovrebbe essere un altro nome di variabile. Non sta trovando, quindi muore e gag.

var bbb = (1,2,3)

Qui, il compilatore prima lo valuta 1e lo ignora. Quindi lo valuta 2e lo ignora. Quindi valuta 3e viene lasciato in pila in modo da essere assegnato abbb

Sebbene l'uso di virgole per separare le espressioni non sia comune, a volte è utile in cose come l' foraspetto.

for (i = 0, l = 10; i < l; i++) {
  console.log(i);
}
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.