JavaScript中&和&&有什么区别?

124

&&&在JavaScript中有什么区别?

示例代码:

var first  = 123;
var second = false;
var third  = 456;
var fourth = "abc";
var fifth  = true;
alert(first & second); // 0
alert(first & third);  // 72
alert(first & fourth); // 0
alert(first & fifth);  // 1

alert(first && second); // false
alert(first && third);  // 456
alert(first && fourth); // abc
alert(first && fifth);  // true

似乎&&是一个逻辑and,如果两个值都是true,则始终返回第二个值。

但是&是什么?

(顺便说一句,在Python中,&&似乎是and; &似乎是Python中的&


1
如果你想知道为什么我们不使用位运算符而是使用逻辑运算符,请考虑 4&1 = 0。使用长度为 4 和 1 的两个数组; 位运算:fruits.length&veggies.length === 0,布尔运算:fruits.length && veggies.length === true - Tom Anderson
4个回答

196

& 是位运算 AND

这个操作符在 JavaScript 中几乎不常用。其他编程语言(如 C 和 Java)使用它来提高性能或处理二进制数据。在 JavaScript 中,由于性能问题并且我们很少处理二进制数据,因此使用该操作符存在疑问。

该操作符需要 两个数字 且返回一个 数字。如果它们不是数字,则会转换为数字。

它是如何工作的?维基百科有一个答案:https://en.wikipedia.org/wiki/Bitwise_operation#AND

&& 是逻辑 AND

通常情况下,程序员使用此运算符检查是否同时满足两个条件,例如:

true && true        // returns true
true && false       // returns false

但是在 JavaScript 中,它被扩展以允许任何数据类型和任意数量的项。它返回:

  • 返回第一个计算结果为 false 的项
  • 否则返回最后一项(如果所有项都是 true-y)

以下是一些示例:

true && false && true         // returns false
true && 20 && 0 && false      // returns 0 (it is first false-y)
10 && "Rok" && true && 100    // returns 100 (as all are true-y)

&& 短路求值

正如上面所示,一旦发现一个条件为假值,后面的条件就不再需要考虑。这使得Javascript可以完全停止求值。这被称为短路求值。

下面的语句不会弹出任何东西,并返回false

true && false && alert("I am quiet!")     // returns false
因此,您可以使用&&运算符作为if语句的更短替代方式。以下两者等效:
if (user.isLoggedIn()) alert("Hello!")
user.isLoggedIn() && alert("Hello!")

几乎所有的JS压缩器都使用这个技巧来节省2个字节。


7
JavaScript 中的 && 运算符不返回布尔值。 - Sanghyun Lee
2
据我所知,&& 返回第一个值,如果它是假值,则返回第二个值。 - duri
2
答案已经完全修订。 - Rok Kralj
2
@user777 如果您的操作只有在两个表单都验证通过时才会发生,那么第二个表单是否经过验证就不重要了。如果第一个表单失败,则整个操作无效。但是这实际上是一个完全不同的问题,因为这个线程全部关于“返回”,而不是在“if语句”中使用。 - Ryan Williams
1
@Sanghyun Lee,明白了 ;) - MMJ
显示剩余4条评论

36

& 是按位"和"。这意味着如果你有两个转换为二进制的数字,结果是一个在两个数字都有 1 的位置上有 1 数字的数字。

  100011  //35
& 111001  //57
---------
  100001  //35 & 57 == 33

另一个要记住的事情是,如果使用位与运算符对JavaScript进行操作,它将会将任何超出范围的值转换为在范围内。例如:const b = 99999999999999999; console.log(b & b); // 1569325056 - 当处理像哈希函数这样经常涉及巨大的神秘数字时,这可能非常有用。 - Matt Fletcher

-2

要确定两个布尔值组合在一起是真还是假,如果您想同时检查它们(例如在网页验证中),可以使用&运算符。 &是按位与。

使用&&运算符时,一旦发现第一个值为false,它将结束评估并不会检查第二个值。


4
在处理布尔值时,不应使用按位与(&)操作符。请参考其他答案,了解该操作符的适当用法。 - FtDRbwLXw6
1
@drrcknlsn,我看了其他答案,但这里的解释非常好,您能提供更多关于您的说法的信息吗? - azerafati
1
@Bludream:这个答案中的解释是错误的。你不应该使用位运算符进行逻辑(布尔)比较。你要使用逻辑(布尔)运算符。它们虽然类似,但功能不同,需要不同的输入,产生不同的输出,并且具有不同的运算符优先级。 - FtDRbwLXw6
2
我同意这是一种不好的做法,但在布尔值中使用&是可行的。false评估为0,true评估为1。我没有看到这个答案在技术上有任何错误,因为你“可以”使用&,只是不建议这样做。 - dyoung

-4

尽管有许多高深的见解,但他们大多忽略了一个条件评估的真相,即只有单个&才能起作用。实际的门外汉的答案解决了我的问题,我一直在使用多个链接的&& IF语句字符串,每个都!==到一个条件,导致失败,并需要合法地使用单个&。我感谢杰克·韦恩(和拉斯)的回答,他们的回答因为正确而被不公正地投票否决,因为当存在多个&&时,它已经停止评估并且在找到第一个评估==!后不再继续进行。对于&&,它认为在第一个评估显示!== [例如false]之后,它的工作已经完成了。我的错误代码是

IF ((sessionStorage.myLable !== "LableStringA") && (sessionStorage.myLable !== "LableStringB") && (sessionStorage.myLableZ !== "LableStringA") && (sessionStorage.myLableZ !== "LableStringB")) { ...)

在这里,正确地用单个&代替&&,这既在现实世界中实用又在技术上是正确的答案。再次感谢杰克·韦恩(和拉斯)对代码洞察力和理解。


2
如果你不理解它,我不建议仅仅因为它能用就使用它。这只会在以后出现问题时让自己陷入麻烦,而且你无法调试它。甚至更糟的是,你尝试在面试中使用它,他们会像ಠ_ಠ一样看着你。如果你的条件语句没有按预期进行评估,那么你就有了逻辑错误。如果第一个条件返回false,那么没有理由评估所有4个条件,因为在这种情况下组合条件永远不能评估为true。 - Brandon
作为对于为什么它看起来并且确实能够优雅地工作的跟进,这将在Russ&Jake被错误诋毁的答案的清晰度中得到解释。所有四个评估都需要进行评估。使用“&&”当第一个评估为false时停止/中止。使用单个“&”使其继续必要地评估剩余的三个条件。正如Russ&Jake所说,“使用“&&”运算符,一旦发现第一个值为false,它将结束评估并不检查第二个值。”而“如果您想检查它们[全部](例如网页上的验证),则可以使用“&”运算符。“&”是按位AND。 - GladHeart
1
如果您需要检查它们全部,您也可以将逻辑结构化为if (!(sessionStorage.myLable === "LableStringA" || sessionStorage.myLable === "LableStringB") || !(sessionStorage.myLableZ === "LableStringA" || sessionStorage.myLableZ === "LableStringB")) { // fail validation},这似乎更清楚地表明了您的意图(我假设您想确保myLable的值是两个值之一或验证失败)。除非您的条件具有副作用,否则没有理由评估它们全部。该运算符的工作方式是正常的,但您的逻辑被颠倒了。 - Brandon
感谢您的跟进,Brandon。尊敬地说,它仍然缺少我这种情况下条件的必要性,其中在每个四个验证中查找===可能是数十种可能性之一。简单来说,如果这四个验证中没有一个包含特定页面标记值,我就会退回到运行脚本来弥补其缺失的状态。所有四个都必须显示为==!。并不是“假设您想确保myLable的值是两个值之一”,而实际上,myLable是众多可能性中的一部分。因此,非等价是需要4次单独的问题。 - GladHeart
换句话说,如果所有四个变量都必须显示为“!==”,那么只要有一个变量不符合要求,就可以停止检查。因为在没有检查完所有变量的情况下,你就已经可以得出“所有四个变量都必须显示为‘!==’”这一期望没有被满足的结论了。 - Tom Anderson
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接