JavaScript中的逗号运算符是什么?

106

如果我使用:

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

3
我很惊讶09在八进制数字中出现非法的数字'9'时居然没有失败。 - recursive
9
@recursive - 在八进制表示中,任何一个数字9都会回退到十进制。 - Yuval Adam
不要混淆参数列表中的逗号。alert只接受一个参数,多余的参数将被丢弃。 - Andrew
@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); } ;解释器必须知道如何使用函数才能知道它需要多少个参数。相反,它会评估所有内容。 - Andrew
5个回答

107

4
我想不出有很多情况下使用逗号运算符能够产生实际效果,除了节省字符(缩小代码)或混淆代码之外。 - user17753
4
"@user17753",它可以在“for”循环的分号分隔部分中合法使用。 - Cyoce
1
@Cyoce:虽然这是正确的,但一般来说,这样的逻辑更清晰地在循环体中执行。有些人会声称他们的方法允许多个continue点而不重复,但是你不应该有多个continue点。 - Lightness Races in Orbit
@user17753 你说得对;我来这里就是因为试图理解一小段压缩的代码。 - Seldom 'Where's Monica' Needy
Vue文档在其模板编译示例中使用它。 - Marinos An

5

还有一些需要考虑的因素:

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


2

具体的语法允许面包店在功能上烘焙面包,将其交给顾客食用,并且通过利用带括号的箭头函数将return的数量保持为零。

(new Array(3)).fill()
.map(()=>({state:"dough", bake(){this.state="baked"}, consume(){this.state="consumed"}}))

.map(bread=>(console.log(`Adding ${bread.state} to oven.`), bread.bake(), bread))
.map(bread=>(console.log(`Consuming ${bread.state} bread.`), bread.consume(), bread))
.map(bread=>console.log(`Bread is now ${bread.state}.`))

Adding dough to oven.
Adding dough to oven.
Adding dough to oven.
Consuming baked bread.
Consuming baked bread.
Consuming baked bread.
Bread is now consumed.
Bread is now consumed.
Bread is now consumed.

如果我使用{};代替(),有什么区别? - Yu Jiaao
1
@YuJiaao 不需要显式地使用关键词 return - Marinos An

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)

3
当然你不会把这样的神秘咒语放到生产代码里,对吧? - Lightness Races in Orbit
@LightnessRacesinOrbit 嗯,我会说这取决于目的(例如教学、缩短代码、无变量/函数声明等)。如果您像我上面那样缩进它,它是完全可读的... 不能停止注意到您使用了“神秘”的词:) - CPHPython
1
呵呵,那甚至不是故意的。 - Lightness Races in Orbit

-2

看一下这里 - 逗号代表多个表达式/语句。例如,在你的代码中,你可以使用像这样的一行:

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

这将声明所有三个变量而不写入:

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

希望这能有所帮助。


28
有点过时,但很重要要注意的是:(1) 你提供的例子没有使用逗号运算符(var声明不使用逗号运算符,即使它是一个逗号)(2)你不能使用逗号运算符来分隔语句,只能用于表达式。 - Qantas 94 Heavy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接