Javascript - Ternary Operator with Multiple Statements

后端 未结 5 1905
Happy的楠姐
Happy的楠姐 2020-11-29 22:29

Is this valid JavaScript? I saw an example where someone used commas in the ternary operator conditions, and it was marked as an error in my editor, and the example didn\'t

相关标签:
5条回答
  • 2020-11-29 22:39

    Expanding on this topic with ES6 code example. If you're using one side of the TRUE : FALSE argument to iterate thru all cases in one IF, it makes sense to separate the code as if it's a switch | case statement.

    Nesting implies that there is branching logic, while it is logically nested, writing nested IF's complicates what we're doing in my example. Like a lawyer over explaining a problem to a jury. IMO, you want to explain the point in it's simplest form. For instance, I find this example the most logical way of expressing nested ifs where the TRUE is executed. The final false is your last else {} choreDoor is either 0,1 or 2:

    choreDoor === 0 ? 
       (openDoor1 = botDoorPath,
        openDoor2 = beachDoorPath,
        openDoor3 = spaceDoorPath)
    : choreDoor === 1 ? 
       (openDoor2 = botDoorPath,
        openDoor1 = beachDoorPath, 
        openDoor3 = spaceDoorPath) 
    : choreDoor === 2 ?
       (openDoor3 = botDoorPath,
        openDoor1 = beachDoorPath, 
        openDoor2 = spaceDoorPath)
    : false;
    
    0 讨论(0)
  • 2020-11-29 22:47

    If you don't want to use the Comma operator (,) then you can use nested Conditional (ternary) operators instead.

    var a = 6;
    var b = 7;
    var c = (a !== b)?  // true
            ((a = 1 || 1===1)? (b = 2) : null) // will first run a=1, then b=2
          : ((a = 0 || 1===1)? (b = 0) : null);
    
    console.log("a = " + a);
    console.log("b = " + b);
    console.log("c = " + c);

    0 讨论(0)
  • 2020-11-29 22:49

    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.

    0 讨论(0)
  • 2020-11-29 22:53

    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... ;-)

    0 讨论(0)
  • 2020-11-29 22:53

    Or you can do this :

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

    Read here about comma operator.

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

    0 讨论(0)
提交回复
热议问题