0

一本书规定了以下 OR 规则:

  • 如果第一个操作数是对象,则返回第一个操作数。
  • 如果第一个操作数的计算结果为 false,则返回第二个操作数。
  • 如果两个操作数都是对象,则返回第一个操作数。
  • 如果两个操作数都为 null,则返回 null。
  • 如果两个操作数都是 NaN,则返回 NaN。
  • 如果两个操作数都未定义,则返回未定义。

但是,我在编码时观察到以下行为:

        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

我怎样才能证明这些规则的这种行为是合理的?

4

4 回答 4

5

这条规则是关键:

如果第一个操作数的计算结果为 false,则返回第二个操作数。

您的所有左侧值都评估为 false,因此返回右侧。

如果对您有帮助,这是 MDN 的一个很好的定义:

expr1 || expr2

如果可以转换为 true,则返回 expr1;否则,返回 expr2。因此,当与布尔值一起使用时,|| 如果任一操作数为真,则返回真;如果两者都为假,则返回假。

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

于 2012-09-08T14:09:39.300 回答
3

对书中描述的混乱感到抱歉。我试图列举边缘情况,我看到这会引起一些混乱。

您可以仅使用两条规则准确地描述该操作:如果第一个参数为真,则返回第一个参数;如果第一个参数是假的,则返回第二个参数。您的第三条规则不仅适用于此运算符,当您尝试使用它时,未声明的变量总是会导致她被抛出。尝试将它用于什么并不重要(typeof 和 delete 除外,它们在未声明的变量中工作正常)。

于 2012-09-09T16:21:06.520 回答
2

您的书选择了一种糟糕的方式来描述逻辑 OR 运算符。

例如,这条规则太局限了。

如果第一个操作数是对象,则返回第一个操作数。

操作员不做任何类型的检查。它不关心第一个或第二个操作数是“对象”。它只关心他们如何强制转换为布尔值。

举这个例子。

"foobar" || false

第一个操作数是字符串,而不是对象,但它会强制转换为 boolean true,因此返回第一个操作数。

Boolean("foobar"); // true

您的书正在遍历要点,就好像它遵循某种指定的算法一样。没有这样的算法。比较严格基于布尔强制。

简而言之,

  • 它从左到右评估操作数,直到找到将强制true执行的操作数或直到它用完操作数。
  • 返回评估的最后一个操作数(非强制)

11.11 二元逻辑运算符

  1. lref是评估 LogicalORExpression 的结果。

  2. 让。lval_GetValue(lref)

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

  4. rref是评估 LogicalANDExpression 的结果。

  5. 返回GetValue(rref)

于 2012-09-08T14:23:08.487 回答
0

是的,观察结果后,我总结了两个简单的规则:

        //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

我认为这一切都在简单的话。这里的任何人都可以确认我是否理解正确吗?我在 IE10 中尝试过这个,希望在其他浏览器中保持一致。

于 2012-09-08T20:38:42.773 回答