A atribuição com vírgula funciona?

108

Por que aaa = 1,2,3funciona e define o valor de aaapara 1?

Por que não var bbb = 1,2,3funciona?

Por que var bbb = (1,2,3)funciona e define o valor de bbbpara 3?

Exemplo de sessão de console

Shankar Cabus
fonte
9
Você obtém o erro de sintaxe porque os nomes das variáveis ​​não podem começar com um número. var a1,a2,a3;irá simplesmente declarar três variáveis ​​locais.
Jared Farrish

Respostas:

200

Há muita coisa acontecendo aqui, mas basicamente, tudo se resume ao operador vírgula .

O operador vírgula avalia seus dois operandos (da esquerda para a direita) e retorna o valor do segundo operando.


Este código:

aaa = 1,2,3

É equivalente a:

aaa = 1;
2;
3;

Portanto, aaaé declarado implicitamente e atribuído um valor de 1. Observe que a saída no console é o resultado da última instrução, 3.


Este código:

var bbb = 1,2,3

É um erro de sintaxe porque as vírgulas em declarações de variáveis ​​são usadas para declarar várias variáveis ​​em uma única linha. Como o artigo MDN aponta,

Observe que a vírgula na varinstrução não é o operador vírgula, porque ela não existe em uma expressão. Em vez disso, é um caractere especial nas varinstruções combinar vários deles em um.

Portanto, este código é aproximadamente equivalente a:

var bbb = 1;
var 2;
var 3;

Claro, 2não é um identificador válido, por isso falha nesse ponto.


Este código:

var bbb = (1,2,3)

É muito semelhante ao primeiro, exceto porque os valores numéricos estão entre parênteses, eles são avaliados primeiro. Portanto, isso é equivalente a:

1;
2;
var bbb = 3;
pswg
fonte
17
Ainda mais, o =in var bbb = 1;não é o mesmo que o =in aaa = 1;- eles vêm de diferentes produções (Initialiser vs AssignmentExpression) na gramática e simplesmente usam o mesmo token.
Ryan Cavanaugh,
7
Explicação muito boa. O que não foi totalmente explícito foi que a = 1, 2, 3pode ser colocado entre parênteses como o (a = 1), 2, 3que avalia como a = 1; 2; 3(e retorna 3, por exemplo b = (a = 1, 2, 3), atribuiria 3 a b). Em contraste, a = (1, 2, 3)avalia como 1; 2; a = 3e retorna 3.
CompuChip
O que o MDN diz sobre os parênteses na atribuição de variáveis ​​e por que isso ocorre ao contrário? Não consegui encontrar o documento
Brian,
@staticx Nada é realmente feito 'ao contrário'. Os parênteses são avaliados primeiro. Assim como quando você o fez (1 + 2) * 3, o 1 + 2é avaliado primeiro e o resultado dessa expressão é substituído de volta na expressão externa para o resto da avaliação.
pswg
9

A vírgula tem vários usos em Javascript. Na expressão:

a = 1, 2, 3;

é um operador que simplesmente retorna seu argumento do lado direito. Mas também faz parte da sintaxe das vardeclarações, que são:

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

(onde [...]significa que essa parte é opcional). Sua vardeclaração não contém os nomes das variáveis ​​após as vírgulas, portanto, ela não analisa. Você pode obter o efeito que deseja com:

var a = (1, 2, 3);

Os parênteses forçam as vírgulas a serem tratadas como operadores em vez de delimitadores entre as declarações de variáveis.

Barmar
fonte
7

Em seus exemplos, a vírgula é usada em dois contextos:

var declaração

A sintaxe da varinstrução é:

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

Aqui, a vírgula é usada para separar os pares nome-valor da variável. O seguinte não funcionará porque um nome de variável não pode começar com um dígito (veja os nomes dos identificadores ):

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

Operador de vírgula

O operador vírgula avalia seus dois operandos (da esquerda para a direita) e retorna o valor do segundo operando. As seguintes expressões funcionam da seguinte maneira:

aaa = 1, 2, 3;
  • aaa = 1, 2 produz 2
    • note que aaa = 1é avaliado primeiro porque =tem uma prioridade maior do que,
  • 2, 3 produz 3
var bbb = (1, 2, 3);
  • a expressão (1, 2, 3)produz 3conforme descrito acima
  • A variável bbbrecebe o valor3
Salman A
fonte
2
aaa = 1, 2, 3=> O operador vírgula é usada para separar os 3 seguintes afirmações: aaa=1, 2e 3. O resultado do operador vírgula é o valor da última instrução 3. No entanto, aaa recebe o valor 1, como pode ser visto claramente na captura de tela do OP. A razão para isso é a precedência do operador, com o operador vírgula tendo a precedência mais baixa.
Tibos 01 de
1

No primeiro caso:

aaa = 1,2,3

as vírgulas servem como separadores de expressão. Ele executa uma atribuição para aaa, em seguida, calcula 2e descarta, então calcula 3e descarta.

No segundo:

var bbb = 1,2,3

A varpalavra-chave diz ao compilador Javascript que a próxima coisa após a ,deve ser outro nome de variável. Não está descobrindo, então morre e engasga.

var bbb = (1,2,3)

Aqui, o compilador primeiro avalia 1e ignora. Em seguida, ele o avalia 2e o ignora. Em seguida, ele avalia 3e isso é deixado na pilha para que seja atribuído abbb

Embora usar vírgulas para separar expressões não seja comum, às vezes é útil em coisas como foraparência.

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