[removed] Conditional (ternary) vs boolean OR for non-boolean values?

前端 未结 4 1986
隐瞒了意图╮
隐瞒了意图╮ 2021-01-13 23:16

In JavaScript, can I always use boolean OR instead of conditional operator for all kind of variables (e.g. string, function, ...)?

For example z = (x || y)

相关标签:
4条回答
  • 2021-01-13 23:35

    They are similar, but are not quite the same. x ? x : y ends up evaluating x twice if x is chosen. This could cause an unexpected effect if x is a function call.

    You can find a formal proof of this in the ECMA specification.

    Another way to prove this:

    function a() { c++; return true; }
    function b() { d++; return true; }
    var c = 0, d = 0;
    a() || 3;
    b() ? b() : 3;
    /* c is 1; d is 2 */
    
    0 讨论(0)
  • 2021-01-13 23:40

    ECMAScript language specification, page 83:

    The production LogicalORExpression : LogicalORExpression || LogicalANDExpression is evaluated as follows:

    1. Let lref be the result of evaluating LogicalORExpression.
    2. Let lval be GetValue(lref).
    3. If ToBoolean(lval) is true, return lval.
    4. Let rref be the result of evaluating LogicalANDExpression.
    5. Return GetValue(rref).

    So the || returns the value of the variable, not the boolean result of operation. This value is converted to boolean by the if (...) statement.

    0 讨论(0)
  • 2021-01-13 23:51

    Those two expressions are equivalent in javascript because the logical "or" operator returns the first element if it's "true" or the second otherwise.

    However you should be careful about what values are true and what are instead considered false because this is different from other dynamically typed languages... for example both "" and 0 are false for Javascript and Python, but [] is false for Python but true for Javascript. In Common Lisp instead everything is considered "true" (including 0 or "" or an empty array) with the only exception of NIL that is considered false (NIL however is also the "empty list").

    Very useful is that undefined is considered "false" by Javascript, as this allows for example to write code like obj.redraw && obj.redraw(); that will call the redraw method only if it's present and doing nothing otherwise (a function/method is "true" for Javascript).

    If with x or y instead you don't mean actually variables but expressions then the two are not equivalent because x in the "ternary operator" version will be evaluated twice (if "true" on the first evaluation) and only once in the "logical or" version. This makes a difference if x is a function call.

    If you want to force a value to its boolean result for Javascript the most common idiom is probably !!x that is always true or false.

    0 讨论(0)
  • 2021-01-13 23:56

    Depends what you are trying to achieve. If you are dealing with strings for instance (x || y) translates to "if string x is not null/empty OR string y is not null/empty" then return 1/true whereas (x ? x : y) translates to "ifstring x is not null/empty then return x otherwise (if it is empty/null) return y". So the first approach will always return you a boolean 1/0 or true/false whereas the second one will return you one of the actual values of the 2 variables. Having said that, if you want to use the result (z) in another if(z) then they are equivalent.

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