Работает ли присваивание через запятую?

108

Почему aaa = 1,2,3работа и установить значение aaaдля 1?

Почему не var bbb = 1,2,3работает?

Почему var bbb = (1,2,3)работа и установить значение bbbдля 3?

Пример консольного сеанса

Шанкар Кабус
источник
9
Вы получаете синтаксическую ошибку, потому что имена переменных не могут начинаться с числа. var a1,a2,a3;просто объявит три локальные переменные.
Джаред Фарриш

Ответы:

200

Здесь много чего происходит, но в основном все сводится к оператору запятой .

Оператор запятой оценивает оба своих операнда (слева направо) и возвращает значение второго операнда.


Этот код:

aaa = 1,2,3

Эквивалентно:

aaa = 1;
2;
3;

So aaaнеявно объявляется, и ему присваивается значение 1. Обратите внимание, что вывод на консоль является результатом последнего оператора 3.


Этот код:

var bbb = 1,2,3

Это синтаксическая ошибка, поскольку запятые в объявлениях переменных используются для объявления нескольких переменных в одной строке. Как указывается в статье MDN,

Обратите внимание, что запятая в varзаявлении не является оператором запятой, потому что она не существует в выражении. Скорее, это специальный символ в varоператорах, позволяющий объединить несколько из них в один.

Итак, этот код примерно эквивалентен:

var bbb = 1;
var 2;
var 3;

Конечно, 2это недействительный идентификатор, поэтому в этот момент он не работает.


Этот код:

var bbb = (1,2,3)

Очень похож на первый, за исключением того, что числовые значения заключены в круглые скобки, они вычисляются первыми. Это примерно эквивалентно:

1;
2;
var bbb = 3;
PSWG
источник
17
Более того, =in var bbb = 1;- это не то же самое, =что и in aaa = 1;- они происходят из разных производств (Initialiser vs AssignmentExpression) в грамматике и просто используют один и тот же токен.
Райан Кавано
7
Очень красивое объяснение. Что не было полностью явным, так это то, что a = 1, 2, 3можно заключить в круглые скобки, как, (a = 1), 2, 3что оценивается как a = 1; 2; 3(и возвращает 3, например b = (a = 1, 2, 3), присваивает 3 переменной b). Напротив, a = (1, 2, 3)оценивается как 1; 2; a = 3и возвращает 3.
CompuChip 01
Что MDN говорит о скобках в присваивании переменных и почему наоборот? Я не смог найти документ
Брайан
@staticx На самом деле ничего не делается «наоборот». В первую очередь оцениваются круглые скобки. Как и в случае с вами (1 + 2) * 3, 1 + 2сначала оценивается, а результат этого выражения подставляется обратно во внешнее выражение для остальной части оценки.
pswg 02
9

Запятая имеет несколько применений в Javascript. В выражении:

a = 1, 2, 3;

это оператор, который просто возвращает свой правый аргумент. Но это также часть синтаксисаvar объявлений, а именно:

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

(где [...]означает, что часть не является обязательной). В вашем varобъявлении отсутствуют имена переменных после запятых, поэтому он не анализируется. Вы можете получить желаемый эффект:

var a = (1, 2, 3);

Круглые скобки заставляют рассматривать запятые как операторы, а не как разделители между объявлениями переменных.

Barmar
источник
7

В ваших примерах запятая используется в двух контекстах:

var заявление

Синтаксис varоператора:

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

Здесь запятая используется для разделения пар имя-значение переменной. Следующее не будет работать, потому что имя переменной не может начинаться с цифры (см. Имена идентификаторов ):

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

Оператор запятой

Оператор запятой оценивает оба своих операнда (слева направо) и возвращает значение второго операнда. Следующие выражения работают следующим образом:

aaa = 1, 2, 3;
  • aaa = 1, 2 дает 2
    • обратите внимание, что aaa = 1оценивается первым, потому что =имеет более высокий приоритет, чем,
  • 2, 3 дает 3
var bbb = (1, 2, 3);
  • выражение (1, 2, 3)дает3 как описано выше
  • Переменной bbbприсваивается значение3
Салман А
источник
2
aaa = 1, 2, 3=> Оператор запятой используются для разделения следующих 3 заявления: aaa=1, 2и 3. Результатом оператора запятой является значение последнего оператора 3. Однако aaa присваивается значение 1, как ясно видно на снимке экрана OP. Причиной этого является приоритет оператора, при этом оператор запятой имеет самый низкий приоритет.
Tibos 01
1

В первом случае:

ааа = 1,2,3

запятые служат разделителями выражений. Он выполняет присвоение aaa, затем вычисляет 2и отбрасывает его, а затем вычисляет3 и отбрасывает его.

Во-вторых:

var bbb = 1,2,3

varКлючевое слово указывает Javascript компилятору , что следующее , что после того, как ,должно быть другое имя переменной. Он не находит, поэтому умирает и давится.

var bbb = (1,2,3)

Здесь компилятор сначала оценивает 1и игнорирует его. Затем он оценивает 2и игнорирует его. Затем он оценивается, 3и он остается в стеке, поэтому он назначаетсяbbb

Хотя использование запятых для разделения выражений не является обычным явлением, иногда это полезно в таких вещах, как forвнешний вид.

for (i = 0, l = 10; i < l; i++) {
  console.log(i);
}
Джереми Дж. Старчер
источник