106

If I use:

1.09 * 1; // returns "1.09"

But if I use:

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

I know that 1,09 isn't a number.

What does the comma do in the last piece of code?

More Examples

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
miken32
  • 42,008
  • 16
  • 111
  • 154
Topera
  • 12,223
  • 15
  • 67
  • 104
  • 3
    I'm surprised that 09 isn't failing for illegal '9' in octal literal. – recursive Aug 24 '10 at 21:11
  • 9
    @recursive - any 9 in octal representation results in a fallback to decimal. – Yuval Adam Aug 24 '10 at 21:14
  • Don't confuse the comma in an argument list. `alert` takes only one argument. Anything after that is discarded. – Andrew Aug 25 '10 at 01:42
  • @Andrew: yes, is discarded by alert(), that takes only one argument, but it will be runned! That's weird. Thanks. – Topera Aug 25 '10 at 01:43
  • 1
    @Topera: not really weird if you think about it from JS's perspective. In JS you don't have to specify your argument list in your function declaration (you can use the `arguments` object instead, which can be of any length). Even with modern compiled JS, there would be no way to tell ahead of time how many arguments a function would take. Consider this: `function test() { args=[]; for (var i = 0; i < arguments.length; i++) { args.push(arguments[i] + 1); } ;` The interpreter would have to know how the function was being used to know how many args it would take. Instead, it evaluates everything. – Andrew Aug 25 '10 at 02:05

5 Answers5

107

The comma operator evaluates both of its operands (from left to right) and returns the value of the second operand.

Source: https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special_Operators/Comma_Operator

For example, the expression 1,2,3,4,5 evaluates to 5. Obviously the comma operator is useful only for operations with side-effects.

console.log(1,2,3,4,5);
console.log((1,2,3,4,5));
Zze
  • 18,229
  • 13
  • 85
  • 118
Yuval Adam
  • 161,610
  • 92
  • 305
  • 395
  • 4
    I can't think of many cases where the comma operator is used to any affect but saving characters (minifying) or obfuscating code. – user17753 Jan 30 '13 at 21:55
  • 4
    @user17753 it can be used legitimately in the semicolon-separated section of a `for` loop. – Cyoce Mar 24 '17 at 07:33
  • 1
    @Cyoce: While that's true, speaking generally such logic is more clearly performed in the loop body. Some people will then claim that their way allows for multiple `continue` points without duplication, but then you shouldn't have multiple `continue` points. – Lightness Races in Orbit Mar 21 '18 at 12:15
  • @user17753 You're on the money; trying to understand a small snippet of minified code is why I'm here – Seldom 'Where's Monica' Needy May 20 '20 at 22:25
  • `Vue` docs use it on their [template compilation example](https://v3.vuejs.org/guide/render-function.html#template-compilation) – Marinos An Apr 21 '21 at 11:14
5

Some more to consider:

console.log((0, 9));
console.log((9, 0));
console.log(("foo", "bar"));
Zze
  • 18,229
  • 13
  • 85
  • 118
Douglas
  • 36,802
  • 9
  • 76
  • 89
2

The specific syntax allows a bakery to functionally bake bread, hand it to the customer for consumption and also keep the number of returns to zero. All these by utilizing parenthesized arrow functions.

(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.
Marinos An
  • 9,481
  • 6
  • 63
  • 96
0

Adding/modifying properties to an object and returning it in the same line is a possible use-case:

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]
// }

The above anonymous function returns an object with random values bigger than the input value or, if there's none, with the input value itself in an array in contained in the bigger property.

It is still syntactic sugar (like arrow functions), but it does shorten the number of lines... I wonder if some JS minifiers detect and adjust the code in a similar way automatically. Run it in your console:

((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
  • 12,379
  • 5
  • 59
  • 71
-2

Have a look here - the comma stands for multiple expressions / statements. For example in your code you could use a line like this:

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

This would declare all three variables without writing:

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

Hope that helps.

Drew Gaynor
  • 8,292
  • 5
  • 40
  • 53
dhh
  • 4,289
  • 8
  • 42
  • 59
  • 28
    It's a bit old, but important to note: (1) the example you have provided doesn't use the comma operator (`var` declarations don't use the comma *operator*, even though it's a comma) and (2) you can't separate statments using the comma operators; only expressions are allowed. – Qantas 94 Heavy Apr 26 '14 at 09:49