L'affectation avec une virgule fonctionne-t-elle?

108

Pourquoi aaa = 1,2,3fonctionne et définit la valeur de aaaà 1?

Pourquoi ça ne var bbb = 1,2,3marche pas ?

Pourquoi var bbb = (1,2,3)fonctionne et définit la valeur de bbbà 3?

Exemple de session de console

Shankar Cabus
la source
9
Vous obtenez l'erreur de syntaxe car les noms de variables ne sont pas autorisés à commencer par un nombre. var a1,a2,a3;déclarera simplement trois variables locales.
Jared Farrish

Réponses:

200

Il se passe beaucoup de choses ici, mais fondamentalement, cela revient à l' opérateur virgule .

L'opérateur virgule évalue ses deux opérandes (de gauche à droite) et renvoie la valeur du deuxième opérande.


Ce code:

aaa = 1,2,3

Est équivalent à:

aaa = 1;
2;
3;

So aaaest implicitement déclaré et attribué une valeur de 1. Notez que la sortie sur la console est le résultat de la dernière instruction, 3.


Ce code:

var bbb = 1,2,3

Est une erreur de syntaxe car les virgules dans les déclarations de variables sont utilisées pour déclarer plusieurs variables sur une seule ligne. Comme le souligne l'article MDN,

Notez que la virgule dans l' varinstruction n'est pas l'opérateur virgule, car elle n'existe pas dans une expression. C'est plutôt un caractère spécial dans les varinstructions pour en combiner plusieurs en une seule.

Donc, ce code équivaut à peu près à:

var bbb = 1;
var 2;
var 3;

Bien sûr, ce 2n'est pas un identifiant valide, donc il échoue à ce stade.


Ce code:

var bbb = (1,2,3)

Est très similaire au premier, sauf parce que les valeurs numériques sont placées entre parenthèses, elles sont évaluées en premier. C'est donc à peu près équivalent à:

1;
2;
var bbb = 3;
pswg
la source
17
De plus, le =in var bbb = 1;n'est pas le même =que le in aaa = 1;- ils proviennent de différentes productions (Initialiser vs AssignmentExpression) dans la grammaire et utilisent simplement le même jeton.
Ryan Cavanaugh
7
Très belle explication. Ce qui n'était pas entièrement explicite, c'est que cela a = 1, 2, 3peut être mis entre parenthèses comme (a = 1), 2, 3qui évalue comme a = 1; 2; 3(et renvoie 3, par exemple b = (a = 1, 2, 3)attribuerait 3 à b). En revanche, a = (1, 2, 3)évalue 1; 2; a = 3et renvoie 3.
CompuChip
Que dit le MDN sur les parens dans l'attribution de variables et pourquoi est-ce l'inverse? Je n'ai pas trouvé le document
Brian
@staticx Rien ne se fait vraiment «à l'envers». Les parenthèses sont évaluées en premier. Tout comme lorsque vous l'avez fait (1 + 2) * 3, le 1 + 2est évalué en premier et le résultat de cette expression est replacé dans l'expression externe pour le reste de l'évaluation.
pswg
9

La virgule a de multiples utilisations en Javascript. Dans l'expression:

a = 1, 2, 3;

c'est un opérateur qui renvoie simplement son argument de droite. Mais cela fait également partie de la syntaxe des vardéclarations, qui sont:

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

(où [...]signifie que cette partie est facultative). Votre vardéclaration ne contient pas les noms de variables après les virgules, elle n'est donc pas analysée. Vous pouvez obtenir l'effet souhaité avec:

var a = (1, 2, 3);

Les parenthèses forcent les virgules à être traitées comme des opérateurs plutôt que comme des délimiteurs entre les déclarations de variables.

Barmar
la source
7

Dans vos exemples, la virgule est utilisée dans deux contextes:

var déclaration

La syntaxe de l' varinstruction est:

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

Ici, la virgule est utilisée pour séparer les paires nom-valeur de variable. Ce qui suit ne fonctionnera pas car un nom de variable ne peut pas commencer par un chiffre (voir les noms d'identifiant ):

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

Opérateur virgule

L'opérateur virgule évalue ses deux opérandes (de gauche à droite) et renvoie la valeur du deuxième opérande. Les expressions suivantes fonctionnent comme suit:

aaa = 1, 2, 3;
  • aaa = 1, 2 donne 2
    • notez qu'il aaa = 1est évalué en premier car il =a une priorité plus élevée que,
  • 2, 3 donne 3
var bbb = (1, 2, 3);
  • l'expression (1, 2, 3)donne 3comme décrit ci-dessus
  • La variable bbbreçoit la valeur3
Salman A
la source
2
aaa = 1, 2, 3=> L'opérateur virgule est utilisé pour séparer les 3 énoncés suivants: aaa=1, 2et 3. Le résultat de l'opérateur virgule est la valeur de la dernière instruction 3. Cependant, aaa reçoit la valeur 1, comme le montre clairement la capture d'écran de l'OP. La raison en est la priorité de l'opérateur, l'opérateur virgule ayant la priorité la plus basse.
Tibos
1

Dans le premier cas:

aaa = 1,2,3

les virgules servent de séparateurs d'expression. Il effectue une affectation à aaa, puis il la calcule 2et la rejette, puis la calcule 3et la rejette.

Dans la seconde:

var bbb = 1,2,3

Le varmot-clé indique au compilateur Javascript que la prochaine chose après a ,devrait être un autre nom de variable. Il ne se trouve pas, alors il meurt et bâillonne.

var bbb = (1,2,3)

Ici, le compilateur l'évalue d'abord 1et l'ignore. Ensuite, il l'évalue 2et l'ignore. Ensuite, il évalue 3et cela reste sur la pile afin qu'il soit affecté àbbb

Bien que l'utilisation de virgules pour séparer les expressions ne soit pas courante, elle est parfois utile dans des choses comme l' forapparence.

for (i = 0, l = 10; i < l; i++) {
  console.log(i);
}
Jeremy J Starcher
la source