Что делает запятая в выражениях JavaScript?

89

Если я использую:

1.09 * 1; // returns "1.09"

Но если я использую:

1,09 * 1; // returns "9"

Я знаю, что 1,09 - это не число.

Что делает запятая в последнем фрагменте кода?

Больше примеров

if (0,9) alert("ok"); // alert
if (9,0) alert("ok"); // don't alert

alert(1); alert(2); alert(3); // 3 alerts
alert(1), alert(2), alert(3); // 3 alerts too

alert("2",
    foo = function (param) {
        alert(param)
    },
    foo('1')
)
foo('3'); // alerts 1, 2 and 3
Topera
источник
1
Я удивлен, что 09 не исключает неправильную «9» в восьмеричном буквальном.
рекурсивный
7
@recursive - любая 9 в восьмеричном представлении приводит к откату к десятичному.
Yuval Adam
Не путайте запятую в списке аргументов. alertпринимает только один аргумент. Все, что после этого, отбрасывается.
Эндрю
@Andrew: да, отбрасывается функцией alert (), которая принимает только один аргумент, но она будет запущена! Это странно. Спасибо.
Topera
1
@Topera: не очень-то странно, если подумать с точки зрения JS. В JS вам не нужно указывать список аргументов в объявлении функции ( argumentsвместо этого вы можете использовать объект, который может быть любой длины). Даже с современным скомпилированным JS не было бы возможности заранее сказать, сколько аргументов примет функция. Подумайте об этом: function test() { args=[]; for (var i = 0; i < arguments.length; i++) { args.push(arguments[i] + 1); } ;интерпретатор должен знать, как функция использовалась, чтобы знать, сколько аргументов потребуется. Вместо этого он оценивает все.
Эндрю

Ответы:

95

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

Источник: https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special_Operators/Comma_Operator

Например, выражение 1,2,3,4,5оценивается как 5. Очевидно, что оператор запятой полезен только для операций с побочными эффектами.

console.log(1,2,3,4,5);
console.log((1,2,3,4,5));

Юваль Адам
источник
2
Они взяли это из C. Я думаю, это полезно только для выражений, которые имеют побочные эффекты.
Радомир Доперальский
3
Я не могу вспомнить много случаев, когда оператор запятой используется для каких-либо действий, кроме сохранения символов (минификации) или запутывания кода.
user17753
1
@ user17753 его можно законно использовать в разделе forцикла, разделенном точкой с запятой .
Cyoce
1
@Cyoce: Хотя это правда, вообще говоря, такая логика более четко реализована в теле цикла. Некоторые люди затем утверждают, что их способ позволяет использовать несколько continueточек без дублирования, но тогда у вас не должно быть нескольких continueточек.
Lightness Races на орбите
@ user17753 Ты на деньгах; пытаюсь понять небольшой фрагмент минифицированного кода - вот почему я здесь
редко «Где Моника» Нуждаюсь
6

Еще кое-что для рассмотрения:

console.log((0, 9));
console.log((9, 0));
console.log(("foo", "bar"));

Дуглас
источник
7
Лол, это весело:alert("1", alert("2", alert("3")))
Topera
1
@ Андрей: Ой, я обновил свой ответ тем, что хотел использовать.
Дуглас
Оператор запятой оценивает каждый из своих операндов (слева направо) и возвращает значение lastоперанда.
xgqfrms
2
Оператор запятой оценивает оба своих операнда (слева направо) и возвращает значение second операнда.

https://stackoverflow.com/a/3561056/5934465

Так должно быть!

Оператор запятой оценивает каждый из своих операндов (слева направо) и возвращает значение lastоперанда.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator

xgqfrms
источник
5
Оператор запятой принимает два операнда, поэтому исходная цитата была правильной. То, о чем вы говорите, является конечным результатом вложенности таких выражений, но это означает, что ваша цитата замены слегка искажена. a,b,c,dis((((a),b),c),d)
Lightness Races in Orbit
1

Посмотрите здесь - запятая означает несколько выражений / операторов. Например, в вашем коде вы можете использовать такую ​​строку:

var a=0, b=0, c=0;

Это объявит все три переменные без записи:

var a=0;
var b=0;
var c=0;

Надеюсь, это поможет.

дхх
источник
23
Это немного устарело, но важно отметить: (1) в приведенном вами примере не используется оператор запятой (в varобъявлениях не используется оператор запятой , даже если это запятая) и (2) вы не можете разделить отчеты с использованием операторов запятой; разрешены только выражения.
Qantas 94 Heavy
0

Возможным вариантом использования является добавление / изменение свойств объекта и возврат его в той же строке :

console.log(
  ((x) => (o = {biggerCond: r => r >= x},
           o.r5 = Array.from(window.crypto.getRandomValues(new Uint16Array(5))),
           o.isAnyBigger = o.r5.some(o.biggerCond),
           o.bigger = o.isAnyBigger ? o.r5.filter(o.biggerCond) : [x], o )
  )(5e4)
);
// Example
// {
//   bigger: [58414, 56500, 63397],
//   isAnyBigger: true,
//   isBiggerCond: r => r >= x,
//   r5: [58414, 12015, 56500, 63397, 43861]
// }

Вышеупомянутая анонимная функция возвращает объект со случайными значениями, превышающими входное значение, или, если их нет, с самим входным значением в массиве, содержащемся в biggerсвойстве.

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

((x)=>(o={biggerCond:r=>r>=x},o.r5=Array.from(window.crypto.getRandomValues(new Uint16Array(5))),o.isAnyBigger=o.r5.some(o.biggerCond),o.bigger=o.isAnyBigger?o.r5.filter(o.biggerCond):[x],o))(5e4)
CPHPython
источник
2
Но, конечно, вы бы не стали вкладывать такие загадочные заклинания в производственный код, верно?
Гонки за легкостью на орбите
@LightnessRacesinOrbit ну, я скажу, это зависит от цели (например, обучение, сокращение кода, отсутствие объявлений переменных / функций и т. Д.). Если вы сделаете отступ, как я сделал выше, он будет прекрасно читаем ... Не могу не заметить, что вы использовали слово «загадочный» :)
CPHPython
1
Хех, это даже не было преднамеренным 😂
Легкость гонки на орбите