10

考虑这种情况:

(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

4

11 回答 11

22

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

if (a && a.length)

你不能简单地&在这里使用。

请注意,当您不处理布尔值时,无法使用&代替。&&例如&on 2( 01in binary) 和4( 10in binary) is 0

还要注意,除了在if测试中,&&(就像||) 也被使用,因为它返回一个操作数

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

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

于 2013-02-14T09:02:03.203 回答
13

按位运算的行为相同吗?

不,这不对。位运算符适用于整数,而逻辑运算符具有截然不同的语义。只有当使用纯布尔值时,结果可能是相似的。

  • 位运算符:计算两个操作数,转换为 32 位整数,对它们进行运算,然后返回数字。
  • 逻辑运算符:评估第一个操作数,如果它是真/假,则评估并返回第二个操作数,否则返回第一个结果。这称为短路评估

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

(true & true & false & false & true) === 0
(true && true && false && false && true) === false
于 2013-02-14T09:04:49.837 回答
9

不,他们不这样做。区别在于:

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

&&(逻辑与)

  1. 检查操作数的真实性
  2. 使用短路并且可能不计算第二个操作数
  3. 返回最后一个计算的操作数而不进行类型转换
a() && b();
// LOG: "a()"
// RET: false

&(按位与)

  1. 临时将操作数转换为其 32 位整数表示(如有必要)
  2. 计算两个操作数
  3. 返回一个数字
a() & b();
// LOG: "a()"
// LOG: "b()"
// RET: 0
于 2013-02-14T09:48:13.703 回答
3

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

第一个说你正在测试真实性

第二个意味着你变出一些魔法。在实际代码中,您将看到variable1 & variable2. 不清楚您实际上是否打算测试真实性(而不是真实性)。代码的读者可能会感到困惑,因为不清楚为什么&要使用。

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

于 2013-02-14T09:04:55.703 回答
3

几乎所有内容都已经说过了,但为了完整起见,我想看看性能方面(你说的无关紧要,但很可能):

JavaScript 有很多难以记住的关于如何计算表达式的规则。当涉及到更复杂的比较时,这包括很多类型转换(隐式类型强制)。数组和对象需要通过调用它们的toString()方法进行转换,然后转换为数字。这会导致巨大的性能损失。

逻辑运算符&&是短路的。这意味着一旦遇到虚假值,评估就会停止并false返回。位运算符将始终评估整个语句。

当涉及非常昂贵的操作(转换数组和对象)时,请考虑以下(是的,非常极端的)短路示例:(性能根据Chromium 90中的https://jsbench.me )

// logical operator
( false && {} && [] ) == true
//  /\ short circuits here
// performance: 805M ops/sec  

// bitwise operator
( false  & {}  & [] ) == true // evaluates the entire statement
// performance: 3.7M ops/sec

您可以看到性能相差 100 倍!

于 2013-02-14T09:30:56.500 回答
2
  1. 布尔值允许短路,这可以是性能提升或安全检查。
  2. 条件中使用的非布尔值。例如,if ( 1 & 2 )将返回 false,而if ( 1 && 2 )将返回 true。
于 2013-02-14T09:03:18.257 回答
1

您不能短路按位运算符。位运算符还可以做更多的事情,而不仅仅是计算布尔表达式。

于 2013-02-14T09:03:14.970 回答
1

有一个巨大的区别:逻辑操作是短路的。这意味着 (true && true && false ) 是最后要执行的事情。这允许强大的构造,例如使用抽象工厂模型var myFunc = mozilla.func || opera.sameFunc || webkit.evenOneMoreVariationOfTheSameConcept;

必须对按位运算的所有子表达式进行完全评估——顺便说一句。无论如何,一个人很少需要评估常量按位或逻辑表达式。

于 2013-02-14T09:04:31.640 回答
1

第一个条件必须先转换然后对位求和。但第二个将检查逻辑和返回值。

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

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

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

于 2013-02-14T09:06:52.637 回答
0

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

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

  • 如果两个都存在,逻辑 && 返回第一个操作数,否则返回 0
  • 逻辑 || 返回第一个现有操作数,否则为 0
  • 如果不存在,则操作数存在:未定义、null、false 或 0
于 2019-11-23T05:20:11.367 回答
-1
var bit1 = (((true & true) & (false & false)) & true), // return 0;
    bit2 = (((true && true) && (false && false)) && true); // return flase

alert(bit1 + ' is not ' + bit2);
于 2013-02-14T12:15:51.190 回答