简体   繁体   English

JavaScript中的逻辑或(||)

[英]Logical OR (||) in JavaScript

A book states following rules for OR: 一本书阐明了OR的以下规则:

  • If the first operand is an object, then the first operand is returned. 如果第一个操作数是一个对象,则返回第一个操作数。
  • If the first operand evaluates to false, then the second operand is returned. 如果第一个操作数的值为false,则返回第二个操作数。
  • If both operands are objects, then the first operand is returned. 如果两个操作数都是对象,则返回第一个操作数。
  • If both operands are null, then null is returned. 如果两个操作数都为null,则返回null。
  • If both operands are NaN, then NaN is returned. 如果两个操作数均为NaN,则返回NaN。
  • If both operands are undefined, then undefined is returned. 如果两个操作数均未定义,则返回未定义。

However I observed following behavior while coding: 但是我在编码时观察到以下行为:

        var result18 = (NaNVar || undefinedVar);  //undefined
        var result19 = (NaNVar || nullVar);  //null
        var result20 = (undefinedVar || NaNVar);  //NaN
        var result21 = (undefinedVar || nullVar); //null
        var result22 = (nullVar || NaNVar); //NaN
        var result23 = (nullVar || undefined);   //undefined

How can I justify this behavior for those rules? 我该如何为这些规则证明这种行为?

This rule is the key: 此规则是关键:

If the first operand evaluates to false, then the second operand is returned. 如果第一个操作数的值为false,则返回第二个操作数。

All of your left hand side values evaluate to false, so the right hand side is returned. 您所有的左侧值都计算为false,因此返回右侧。

Here's a good definition from MDN if it helps you: 如果可以帮助您,以下是MDN的一个很好的定义:

expr1 || expr1 || expr2 expr2

Returns expr1 if it can be converted to true; 如果可以将其转换为true,则返回expr1;否则,返回false。 otherwise, returns expr2. 否则,返回expr2。 Thus, when used with Boolean values, || 因此,当与布尔值一起使用时,|| returns true if either operand is true; 如果任一操作数为true,则返回true;否则为false。 if both are false, returns false. 如果两者均为假,则返回false。

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Logical_Operators https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Operators/Logical_Operators

Sorry for the confusion around the description in the book. 对不起,本书中的描述令人困惑。 I was trying to enumerate edge cases and I see how that could cause some confusion. 我试图枚举边缘情况,我发现这可能引起一些混乱。

You can accurately describe the operation using only two rules: if the first argument is truthy then return the first argument; 您可以仅使用两个规则来准确描述操作:如果第一个参数为真,则返回第一个参数; if the first argument is falsy return the second argument. 如果第一个参数为假,则返回第二个参数。 Your third rule doesn't just apply to this operator, an undeclared variable will always causing her to be thrown when you try to use it. 您的第三条规则不仅适用于该运算符,当您尝试使用它时,未声明的变量将始终导致她被抛出。 It doesn't matter what you try to use it for (with the exception of typeof and delete, which work fine in undeclared variables). 不管您打算使用它什么都没有关系(typeof和delete除外,它们在未声明的变量中可以正常工作)。

Your book has chosen a terrible way to describe the logical OR operator. 您的书选择了一种描述逻辑OR运算符的可怕方法。

For example, this rule is far too limiting. 例如,此规则过于局限。

If the first operand is an object, then the first operand is returned. 如果第一个操作数是一个对象,则返回第一个操作数。

The operator does not do any sort of type check. 操作员不执行任何类型的检查。 It doesn't care if the first or second operand is an "object". 不管第一个操作数还是第二个操作数是“对象”。 It only cares about how they coerce to a boolean. 它只关心它们如何强制转换为布尔值。

Take this example. 举这个例子。

"foobar" || false

The first operand is a string, not an object, but it will coerce to the boolean true , so the first operand is returned. 第一个操作数是一个字符串,而不是一个对象,但是它将强制转换为布尔值true ,因此返回第一个操作数。

Boolean("foobar"); // true

Your book is walking through bullet points as though it was following some sort of specified algorithm. 您的书正在遵循要点,就好像它遵循某种指定的算法一样。 There is no such algorithm. 没有这样的算法。 The comparison is strictly based on Boolean coercion. 比较严格地基于布尔强制。

To put it simply, 简而言之,

  • it evaluates operands from left to right until one is found that will coerce to true or until it runs out of operands. 它从左到右评估操作数,直到找到一个将强制转换为true的操作数,或者用完为止。
  • the last operand evaluated is returned (uncoerced) 返回评估的最后一个操作数(非强制)

11.11 Binary Logical Operators 11.11二元逻辑运算符

  1. Let lref be the result of evaluating LogicalORExpression. lref为评估LogicalORExpression的结果。

  2. Let lval be GetValue(lref) . lvalGetValue(lref)

  3. If ToBoolean(lval) is true , return lval . 如果ToBoolean(lval)true ,则返回lval

  4. Let rref be the result of evaluating LogicalANDExpression. rref为评估LogicalANDExpression的结果。

  5. Return GetValue(rref) . 返回GetValue(rref)

Yes after observing the results, I concluded two simple rules: 是的,观察结果后,我得出了两个简单的规则:

        //1: if the first operand evaluates to true then it is returned (here it means actual //value of operand is returned but not the evaluated value that is true)
        //following values evaluates to ture: non-empty string, non-zero number and //none of these values- NaN, null, undefined

        var result = ("Mahesh" || false) //"Mahesh"
        var result = ("Mahesh" || true) //"Mahesh"
        var result = ("Mahesh" || undefined) //"Mahesh"
        var result = ("Mahesh" || null) //"Mahesh"
        var result = ("Mahesh" || NaN) //"Mahesh"
        var result = (5 || false) //5
        var result = (5 || true) //5
        var result = (5 || null) //5
        var result = (5 || NaN) //5
        var result = (5 || undefined) //5

        //2: if first operand evaluates to false then the value of second operand is //returned, again without evaluating it
        //following values evaluate to false: empty string (""), number zero (0),  null, //NaN, undefined or false)

        var result = (false || NaN);  //NaN
        var result = (false || null);  //null
        var result = (false || undefined);  //undefined
        var result = (false || "Mahesh");  //Mahesh
        var result = (false || 5);  //5

        var result = (NaN || false);   //false
        var result = (NaN || true);   //true
        var result = (NaN || NaN);   //NaN
        var result = (NaN || null);  //null
        var result = (NaN || undefined);  //undefined
        var result = (NaN || "Mahesh");   //Mahesh
        var result = (NaN || 5);   //5

        var result = (null || false);  //false
        var result = (null || true);  //true
        var result = (null || NaN); //NaN
        var result = (null || null);  //null
        var result = (null || undefined);   //undefined
        var result = (null || "Mahesh");  //Mahesh
        var result = (null || 5);  //5

        var result = (undefined || false);  //false    
        var result = (undefined || true);  //true
        var result = (undefined || NaN);  //NaN
        var result = (undefined || null); //null
        var result = (undefined || undefined);  //undefined
        var result = (undefined || "Mahesh");  //Mahesh
        var result = (undefined || 5);  //5

        var result = (0 || false); //false
        var result = (0 || true); //true
        var result = (0 || NaN); //NaN
        var result = (0 || null);  //null
        var result = (0 || undefined);   //undefined
        var result = (0 || "Mahesh"); //Mahesh
        var result = (0 || 5); //5

        var result = ("" || false); //false
        var result = ("" || true); //true
        var result = ("" || NaN); //NaN
        var result = (""|| null);  //null
        var result = (""|| undefined);   //undefined
        var result = ("" || "Mahesh"); //Mahesh
        var result = ("" || 5); //5

        //Note: if the first operand evaluates to false and if the second operand is undeclared 
        //variable then it will cause an error
        var result = (false || undeclaredVar);    //error

I think that's all in it in simpler words. 我认为这就是所有这些。 Can anyone here confirm if I have got right understanding? 在座的任何人都可以确认我是否正确理解了吗? I tried this in IE10, hope things will be consistent across other browsers. 我在IE10中尝试过此方法,希望其他浏览器之间保持一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM