逗号在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

1
我很惊讶09的八进制字面量中的非法“ 9”没有失败。
递归

7
@recursive-八进制表示形式中的任何9都会导致回退到十进制。
Yuval Adam

不要混淆参数列表中的逗号。alert仅接受一个论点。之后的所有内容都将被丢弃。
安德鲁(Andrew)2010年

@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); } ;解释器将必须知道如何使用该函数来知道需要多少个args。相反,它将评估所有内容。
安德鲁

Answers:


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 in Orbit

@ user17753你赚了钱;试图理解一小段简短代码的原因是我在这里的原因
很少出现“莫妮卡在哪里” Needy

6

还有更多需要考虑的问题:

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


7
大声笑,这很有趣:alert("1", alert("2", alert("3")))
Topera

1
@Andrew:糟糕,我已经用我的意思更新了答案。
道格拉斯

逗号运算符评估每个操作数(从左到右)并返回该last操作数的值。
xgqfrms

2
逗号运算符计算两个操作数(从左到右)并返回second 操作数的值。

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

应该是这样的!

逗号运算符评估每个操作数(从左到右)并返回该last操作数的值。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Comma_Operator


5
逗号运算符采用两个操作数,因此原始引用是正确的。您所说的是嵌套此类表达式的最终结果,但这意味着您的替换引号含糊不清。a,b,c,d((((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)您无法分开使用逗号运算符的语句;只允许使用表达式。
澳洲航空94重型

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)

2
但是,您当然不会在生产代码中加入这种隐晦的咒语,对吗?
Lightness Races in Orbit

@LightnessRacesinOrbit很好,我会说这取决于目的(例如,教学,缩短代码,没有变量/函数声明等)。如果像我上面那样缩进,它是完全可读的...无法停止注意到您使用了“神秘”一词:)
CPHPython

1
嘿,这甚至不是故意的
亮度赛跑在
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.