Javascript - Ternary Operator with Multiple Statements

Yes:

a=1;
b=2;

a!==b ? (a=1, b=2) : (a=2, b=1)

console.log(a);     // 1
console.log(b);     // 2

and:

a=1;
b=2;

a===b ? (a=1, b=2) : (a=2, b=1)

console.log(a);     // 2
console.log(b);     // 1

As you can analyze, changing the equality operator reacts correctly to our test if you look at the results.


Yes, it's valid, and it runs fine in Chrome:

var a, b, c;

a = 6;
b = 7;
c = a !== b ? (a = 1, b = 2) : (a = 2, b = 1);
console.log("a = " + a);
console.log("b = " + b);
console.log("c = " + c);

I'm not saying it's a remotely good idea in code humans are meant to read. :-) I expect jamietre is correct in the comments when he/she says it looks like the result of minification.

The comma operator is a binary operator (an operator accepting two operands). It evaluates its left-hand operand (thus causing any side-effects it has, such as assignment), throws that result away, then evalutes its right-hand operand (thus causing its side-effects if any) and takes that result as its result value. If you have multiple comma operators in a row, the overall expression is evaluated in order, left-to-right, with the final result being the value resulting from the right-most operand evaluation.

And of course, you know the conditional operator (a ternary operator — one accepting three operands) is used to pick one of two sub-expressions to evaluate, on the basis of an initial expression.

So that line is very...expressive...what with a total of seven* different expressions inside it.

So in that example, the result of the overall expression is 2 if a !== b initially, or 1 if a === b initially, with the side-effects of setting a and b.

It's the side effects that make it, in my view, a questionable choice. And of course, there's no reason to use the comma operator if the left-hand operand doesn't have side effects.


* Yes, seven of 'em packed into that overall ternary:

  • a !== b
  • the first comma expression
  • a = 1
  • b = 2
  • the second comma expression
  • a = 2
  • b = 1

Re your edit with the actual statement, that one works too:

function test(a) {
    var b = 7,
        d = 1,
        e = 2,
        f = 3,
        g = 4,
        h = 5,
        i = 6;
    
    a!==0?b<0?(h=b/a,e=h-1,f=-2*b+2*a*e,i=-2*b+2*a*h,d=2*h*a-2*b-2*a):(h=b/a,e=h+1,f=2*b-2*a*e,i=2*b-2*a*h,d=-2*h*a+2*b):d=h=e=f=i=0;
    
    console.log("a = " + a);
    console.log("b = " + b);
    console.log("d = " + d);
    console.log("e = " + e);
    console.log("f = " + f);
    console.log("g = " + g);
    console.log("h = " + h);
    console.log("i = " + i);
}

test(0);
test(1);
.as-console-wrapper {
  max-height: 100% !important;
}

But wow, I hope this is minified, because if a person wrote that, they must really have a thing against anyone who's supposed to maintain it later... ;-)

Tags:

Javascript