为什么在按位运算符执行相同操作时使用逻辑运算符?

时间:2013-02-14 08:59:07

标签: javascript operators bitwise-operators logical-operators

考虑这个条件:

(true & true & false & false & true) == true //returns: false

如您所见,按位AND行为与逻辑AND完全相同:

(true && true && false && false && true) == true //returns: false

我想知道为什么当按位操作与逻辑操作相同时,我应该使用逻辑操作。

注意:请不要因为性能问题而回答这个问题,因为它在Mozilla Firefox中要快得多,请参阅此jsPerf:http://jsperf.com/bitwise-logical-and

11 个答案:

答案 0 :(得分:20)

使用逻辑运算符进行短路评估的最常见用途不是性能,而是避免错误。见:

if (a && a.length)

您不能在此处使用&

请注意,当您不处理布尔值时,无法使用&代替&&。例如&上的2(二进制为01)和4(二进制为10)为0

另请注意,除了if测试之外,还使用了&&(就像||),因为it returns one of the operands

"a" & "b" => 0
"a" && "b" => "b"

更一般地说,通常可以使用&代替&&。就像省略javascript代码中的大多数;一样。但它会迫使你思考不必要的事情(或者会不时给你带来奇怪的错误)。

答案 1 :(得分:11)

  

按位运算行为相同吗?

不,不是。按位运算符处理整数,而逻辑运算符具有不同的语义。只有在使用纯布尔时,结果可能类似。

  • Bitwise operators:重新评估两个操作数,转换为32位整数,对它们进行操作,然后返回数字。
  • Logical operators:评估第一个操作数,如果它是truthy / falsy然后evalutate并返回第二个操作数,则返回第一个结果。这称为Short-circuit evaluation

您已经可以看到结果类型的这种差异:

(true & true & false & false & true) === 0
(true && true && false && false && true) === false

答案 2 :(得分:8)

不,他们不这样做。不同之处是:

  1. 操作数类型是否已转换
  2. 是否评估两个操作数
  3. 返回值
  4. // sample functions 
    function a() { console.log("a()"); return false; }
    function b() { console.log("b()"); return true; }
    

    &安培;&安培; (逻辑与)

    1. 检查操作数的真实性
    2. 使用短路,可能无法评估第二个操作数
    3. 返回没有类型转换的最后一个评估操作数
    4. a() && b();
      // LOG: "a()"
      // RET: false
      

      &安培; (按位AND)

      1. 暂时将操作数转换为32位整数表示(如有必要)
      2. 评估两个操作数
      3. 返回一个数字
      4. a() & b();
        // LOG: "a()"
        // LOG: "b()"
        // RET: 0
        

答案 3 :(得分:3)

因为使用&&&传达了不同的意图。

第一个说你正在测试truthiness

第二个意味着你会变得有点神奇。在实际代码中,您将看到variable1 & variable2。它 代码的读者可能会感到困惑,因为使用&的原因并不明显。

此外,在考虑除bool和函数调用之外的其他值时,语义完全不同,正如许多其他帖子所指出的那样。

答案 4 :(得分:2)

  1. 布尔值允许短路,这可以是性能提升或安全检查。
  2. 条件中使用的非布尔值。例如,if ( 1 & 2 )将返回false,而if ( 1 && 2 )将返回true。

答案 5 :(得分:2)

几乎所有内容都已经说过,但为了完整起见,我想看看性能方面:

JavaScript在如何评估表达式方面有很多难以记住的规则。这涉及到更复杂的比较时的大量演员。需要通过调用它们的toString()方法来转换数组和对象,然后将其转换为数字。这是巨大的性能影响。

当涉及数组和对象时,请考虑以下短路示例:

( false  & {}  & [] ) == true
( false && {} && [] ) == true

<强> Performance DOES matter

答案 6 :(得分:1)

您不能使按位运算符短路。此外,按位运算符可以执行更多操作,而不仅仅是计算布尔表达式。

答案 7 :(得分:1)

存在巨大差异:逻辑运算被短路。这意味着(true&amp;&amp; true&amp;&amp; false)是最后要执行的事情。这允许使用var myFunc = mozilla.func || opera.sameFunc || webkit.evenOneMoreVariationOfTheSameConcept;

等强大的构造,例如抽象工厂模型

必须完全评估所有按位运算的子表达式 - 以及btw。无论如何,我们很少需要评估常量的按位或逻辑表达式。

答案 8 :(得分:1)

第一个条件必须转换为第一个和总和位。但第二个将检查逻辑和返回值。

所以第一个会慢于第二个。

运行此测试:http://jsperf.com/bitwise-logical

在Chrome&amp; IE Bitwise较慢 但在FireFox上逻辑较慢

答案 9 :(得分:0)

按位运算符(&和|)将两个操作数转换为32位“整数”,并作为结果返回位运算。如果不是数字,则操作数的转换为0。

逻辑运算符(&&和||)根本不是逻辑,而是操作数之一或0的选择器。

  • 如果两个都存在,则逻辑&&返回第一个操作数,否则返回0
  • 逻辑||返回第一个现有操作数,否则返回0
  • 如果没有,则存在一个操作数:undefined,null,false或0

答案 10 :(得分:-1)

var bit1 = (((true & true) & (false & false)) & true), // return 0;
    bit2 = (((true && true) && (false && false)) && true); // return flase

alert(bit1 + ' is not ' + bit2);