zoukankan      html  css  js  c++  java
  • 【转】The && and || Operator in JavaScript

    原文: https://blog.mariusschulz.com/2016/05/25/the-andand-and-operator-in-javascript

    The && and || Operator in JavaScript

    -------------------------------------------------

    Similar to other C-like programming languages, JavaScript defines the two operators && and || which represent the logical AND and OR operations, respectively. Using only the two boolean values true and false, we can generate the following truth tables:

    // Logical AND operation
    true  && true;  // true
    true  && false; // false
    false && true;  // false
    false && false; // false
    
    // Logical OR operation
    true  || true;  // true
    true  || false; // true
    false || true;  // true
    false || false; // false
    

    If applied to boolean values, the && operator only returns true when both of its operands are true (and false in all other cases), while the || operator only returns false when both of its operands are false (and true in all other cases).

    Using Logical Operators with Non-Boolean Values

    In JavaScript, the logical operators have different semantics than other C-like languages, though. They can operate on expressions of any type, not just booleans. Also, the logical operators do not always return a boolean value, as the specification points out in section 12.12:

    The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions.

    The following examples showcase some values produced by && and ||:

    "foo" && "bar"; // "bar"
    "bar" && "foo"; // "foo"
    "foo" && "";    // ""
    ""    && "foo"; // ""
    
    "foo" || "bar"; // "foo"
    "bar" || "foo"; // "bar"
    "foo" || "";    // "foo"
    ""    || "foo"; // "foo"
    

    Both && and || result in the value of (exactly) one of their operands:

    • A && B returns the value A if A can be coerced into false; otherwise, it returns B.
    • A || B returns the value A if A can be coerced into true; otherwise, it returns B.

    They select one of their operands, as noted by Kyle Simpson in his You Don't Know JS series:

    In fact, I would argue these operators shouldn't even be called "logical operators", as that name is incomplete in describing what they do. If I were to give them a more accurate (if more clumsy) name, I'd call them "selector operators," or more completely, "operand selector operators."

    Control Flow Structures and Truthy Values

    In practice, you might not even notice that && and || don't always produce a boolean value. The body of control flow structures like if-statements and loops will be executed when the condition evaluates to a "truthy" value, which doesn't have to be a proper boolean:

    let values = [1, 2, 3];
    
    while (values.length) {
        console.log(values.pop());
    }
    
    // 3
    // 2
    // 1
    

    So when is a value considered "truthy"? In JavaScript, all values are considered "truthy", except for the following six "falsy" values:

    • false
    • undefined
    • null
    • NaN
    • 0 (both +0 and -0)
    • ""

    The above while-loop works because after popping the last element, values.length returns the "falsy" value 0. Therefore, the loop body won't be executed and the loop terminates.

    Truthy and Falsy Return Values

    Let's look at an example where it actually matters that && and || don't necessarily produce a boolean value. Imagine you're developing a web application. Users can be signed out, in which case the user object is null, or they can be signed in, in which case the user object exists and has an isAdmin property.

    If you wanted to check whether the current user is an administrator, you would first check whether the user is authenticated (that is, user is not null). Then, you would access the isAdmin property and check whether it's "truthy":

    let user = { isAdmin: true };
    
    // ...
    
    if (user && user.isAdmin) {
        // ...
    }
    

    You might even consider extracting the expression user && user.isAdmin into a separate isAdministrator function so you can use it in multiple places without repeating yourself:

    function isAdministrator(user) {
        return user && user.isAdmin;
    }
    
    let user = { isAdmin: true };
    
    if (isAdministrator(user)) {
        // ...
    }
    

    For user objects with a boolean isAdmin property, either true or false will be returned, just as intended:

    isAdministrator({ isAdmin: true });  // true
    isAdministrator({ isAdmin: false }); // false
    

    But what happens if the user object is null?

    isAdministrator(null); // null
    

    The expression user && user.isAdmin evaluates to null, its first operand, because usercontains a "falsy" value. Now, a function called isAdministrator should only return boolean values, as the prefix is in the name suggests.

    Coercion to Boolean Values

    In JavaScript, a common way to coerce any value into a boolean is to apply the logical NOT operator ! twice:

    function isAdministrator(user) {
        return !!(user && user.isAdmin);
    }
    

    The ! operator, produces the value false if its single operand can be coerced into true; otherwise, it returns true. The result is always a proper boolean, but the truthiness of the operand is flipped. Applying the ! operator twice undoes the flipping:

    !!true = !false = true
    !!false = !true = false
    
    !!0 = !true = false
    !!1 = !false = true
    

    Another option would've been to call the Boolean function, which is a slightly more explicit way to convert a given value to a proper boolean value:

    function isAdministrator(user) {
        return Boolean(user && user.isAdmin);
    }
    

    Conclusion

    In JavaScript, && and || don't always produce a boolean value. Both operators always return the value of one of their operand expressions. Using the double negation !! or the Booleanfunction, "truthy" and "falsy" values can be converted to proper booleans.

  • 相关阅读:
    分享一下前一段时间的开发总结
    循环,梦
    从C#程序中调用非受管DLLs
    大学生零工资就业,谁之过?
    国外宽带用户的上网速度能达到多少呢?
    天沉沉,来个好天气吧
    虚伪,不只是形容一个人
    回头思考关于xml的使用
    从毕业生当中看人与人的差距
    C# 编码规则
  • 原文地址:https://www.cnblogs.com/oxspirt/p/9413696.html
Copyright © 2011-2022 走看看