Why don't logical operators (&& and ||) always return a boolean result?

后端 未结 9 1719
耶瑟儿~
耶瑟儿~ 2020-11-22 06:04

Why do these logical operators return an object and not a boolean?

var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );

var _ = obj &&          


        
相关标签:
9条回答
  • 2020-11-22 06:39

    In most programming languages, the && and || operators returns boolean. In JavaScript it's different.


    OR Operator:

    It returns the value of the first operand that validates as true (if any), otherwise it returns the value of the last operand (even if it validates as false).

    Example 1:

    var a = 0 || 1 || 2 || 3;
            ^    ^    ^    ^
            f    t    t    t
                 ^
                 first operand that validates as true
                 so, a = 1
    

    Example 2:

    var a = 0 || false || null || '';
            ^    ^        ^       ^
            f    f        f       f
                                  ^
                                  no operand validates as true,
                                  so, a = ''
    

    AND Operator:

    It returns the value of the last operand that validates as true (if all conditions validates as true), otherwise it returns the value of the first operand that validates as false.

    Example 1:

    var a = 1 && 2 && 3 && 4;
            ^    ^    ^    ^
            t    t    t    t
                           ^
                           last operand that validates as true
                           so, a = 4
    

    Example 2:

    var a = 2 && '' && 3 && null;
            ^    ^     ^    ^
            t    f     t    f
                 ^
                 entire condition is false, so return first operand that validates as false,
                 so, a = ''
    

    Conclusion:

    If you want JavaScript to act the same way how other programming languages work, use Boolean() function, like this:

    var a = Boolean(1 || 2 || 3);// a = true
    
    0 讨论(0)
  • 2020-11-22 06:39

    I think you have basic JavaScript methodology question here.

    Now, JavaScript is a loosely typed language. As such, the way and manner in which it treats logical operations differs from that of other standard languages like Java and C++. JavaScript uses a concept known as "type coercion" to determine the value of a logical operation and always returns the value of the first true type. For instance, take a look at the code below:

    var x = mystuff || document;
    // after execution of the line above, x = document
    

    This is because mystuff is an a priori undefined entity which will always evaluate to false when tested and as such, JavaScript skips this and tests the next entity for a true value. Since the document object is known to JavaScript, it returns a true value and JavaScript returns this object.

    If you wanted a boolean value returned to you, you would have to pass your logical condition statement to a function like so:

    var condition1 = mystuff || document;
    
    function returnBool(cond){
      if(typeof(cond) != 'boolean'){ //the condition type will return 'object' in this case
         return new Boolean(cond).valueOf();
      }else{ return; }
    }    
    // Then we test...
    var condition2 = returnBool(condition1);
    window.console.log(typeof(condition2)); // outputs 'boolean' 
    
    0 讨论(0)
  • 2020-11-22 06:44

    Compare:

    var prop;
    if (obj.value) {prop=obj.value;}
    else prop=0;
    

    with:

    var prop=obj.value||0;
    

    Returning a truthy expression - rather than just true or false - usually makes your code shorter and still readable. This is very common for ||, not so much for &&.

    0 讨论(0)
  • 2020-11-22 06:48

    You should think of the short-circuit operators as conditionals rather than logical operators.

    x || y roughly corresponds to:

    if ( x ) { return x; } else { return y; }  
    

    and x && y roughly corresponds to:

    if ( x ) { return y; } else { return x; }  
    

    Given this, the result is perfectly understandable.


    From MDN documentation:

    Logical operators are typically used with Boolean (logical) values. When they are, they return a Boolean value. However, the && and || operators actually return the value of one of the specified operands, so if these operators are used with non-Boolean values, they will return a non-Boolean value.

    And here's the table with the returned values of all logical operators.

    0 讨论(0)
  • 2020-11-22 06:51
    var _ = ((obj.fn && obj.fn() ) || obj._ || ( obj._ == {/* something */}))? true: false 
    

    will return boolean.

    UPDATE

    Note that this is based on my testing. I am not to be fully relied upon.

    It is an expression that does not assign true or false value. Rather it assigns the calculated value.

    Let's have a look at this expression.

    An example expression:

    var a = 1 || 2;
    // a = 1
    
    // it's because a will take the value (which is not null) from left
    var a = 0 || 2;
    // so for this a=2; //its because the closest is 2 (which is not null)
    
    var a = 0 || 2 || 1;    //here also a = 2;
    

    Your expression:

    var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );
    
    // _ = closest of the expression which is not null
    // in your case it must be (obj.fn && obj.fn())
    // so you are gettig this
    

    Another expression:

    var a = 1 && 2;
    // a = 2
    
    var a = 1 && 2 && 3;
    // a = 3 //for && operator it will take the fartest value
    // as long as every expression is true
    
    var a = 0 && 2 && 3;
    // a = 0
    

    Another expression:

    var _ = obj && obj._;
    
    // _ = obj._
    
    0 讨论(0)
  • 2020-11-22 06:53

    First, it has to be true to return, so if you are testing for truthfulness then it makes no difference

    Second, it lets you do assignments along the lines of:

    function bar(foo) {
        foo = foo || "default value";
    
    0 讨论(0)
提交回复
热议问题