JavaScript OR (||) 变量赋值说明

IT技术 javascript variables variable-assignment or-operator
2021-01-31 00:24:17

鉴于这段 JavaScript 代码......

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f = a || b || c || d || e;

alert(f); // 4

有人可以向我解释这种技术的名称吗(我最好的猜测是在这个问题的标题中!)?以及它如何/为什么完全起作用?

我的理解是,变量f将被分配到第一个变量的最接近的值(从左到右),该变量的值既不是 null 也不是未定义的,但我没有找到太多关于这种技术的参考资料,并且有看到它用了很多。

另外,这种技术是否特定于 JavaScript?我知道在 PHP 中做类似的事情会f得到一个真正的布尔值,而不是d它本身的值

6个回答

有关说明,请参阅短路评估这是实现这些运算符的常用方法;它不是 JavaScript 独有的。

我已经看到这种技术多年了,但是当我想使用它时让我震惊的是表达式的结果没有转换为布尔值。你以后不能做if( true == f )如果整数存储在 f 中,则此测试将始终返回 false。
2021-03-10 00:24:17
不确定这是否是对初学者的最佳解释。我会推荐:javascript.info/logical-operators
2021-03-24 00:24:17
实际上,您可以这样做if(true == f),这与if(f): 测试会通过是一样的如果你也想测试f,使用严格的比较:if(true === f),这确实会失败。
2021-04-06 00:24:17
是的,短路评估很常见。但这里的区别在于 JavaScript 返回停止执行的最后一个值的方式。@Anurag 的回答在解释这一点方面做得更好。
2021-04-06 00:24:17
请注意“陷阱”,即最后一个总是会被分配,即使它们都是未定义的、空的或假的。在链的末尾设置一些你知道不是 false、null 或 undefined 的东西是表示没有发现任何东西的好方法。
2021-04-07 00:24:17

这样做是为了分配一个默认值,在这种情况下y,如果x变量为,则为 的

JavaScript 中的布尔运算符可以返回一个操作数,而不是其他语言中的布尔结果。

||如果第一个操作数为假,则逻辑 OR 运算符 ( ) 返回其第二个操作数的值,否则返回第一个操作数的值。

例如:

"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"

值是那些false在布尔上下文中使用时强制的值,它们是0, null, undefined, 一个空字符串,NaN当然还有false.

+1 还有这样的运营商吗?或者是||独家的。
2021-03-29 00:24:17
Falsy实际上是技术术语。
2021-04-02 00:24:17
@Alex NB:“真实”(!“真实”)
2021-04-02 00:24:17
所以我们在这篇文章中了解了 ||、&&、“Falsy”和“Truly”。“隐藏”礼物的最佳答案。
2021-04-07 00:24:17
@Support (@Oscar):逻辑&&运算符有类似的行为,如果第一个操作数本身为,则返回第一个操作数的值,并返回第二个操作数的值,仅当第一个操作数为真时,例如("foo" && "bar") == "bar"(0 && "bar") == 0
2021-04-08 00:24:17

Javacript使用短路评价为逻辑运算符||&&但是,它与其他语言的不同之处在于它返回停止执行的最后一个值的结果,而不是一个true, 或false值。

以下值在 JavaScript 中被认为是假的。

  • 错误的
  • 空值
  • "" (空字符串)
  • 0
  • 不明确的

忽略运算符优先级规则并保持简单,以下示例显示哪个值停止了评估,并作为结果返回。

false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"

前 5 个值NaN是假的,所以它们都是从左到右求值的,直到它遇到第一个真值——"Hello"这使得整个表达式为真,所以后面的任何值都不会被求值,并"Hello"作为表达式的结果返回. 同样,在这种情况下:

1 && [] && {} && true && "World" && null && 2010 // null

前 5 个值都是真值并进行求值,直到遇到第一个假值 ( null) 使表达式为假,因此2010不再求值,并null作为表达式的结果返回。

你给出的例子是利用 JavaScript 的这个属性来执行赋值。它可以用于需要在一组值中获得第一个真值或假值的任何地方。下面的代码会将值分配给"Hello"b因为它可以更轻松地分配默认值,而不是执行 if-else 检查。

var a = false;
var b = a || "Hello";

您可以将以下示例称为对该功能的利用,我相信它会使代码更难阅读。

var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);

在警报内部,我们检查是否messages为假,如果是,则评估并返回noNewMessagesText,否则评估并返回newMessagesText因为在这个例子中它是假的,我们在 noNewMessagesText 和 alert 处停止"Sorry, you have no new messages."

同意,这是我最喜欢的答案,因为它专门解决了 JavaScript 变量赋值问题。此外,如果您选择使用三元作为后续变量之一来测试赋值(在运算符之后),则必须将三元括在括号中,以便赋值评估正常工作。
2021-03-28 00:24:17
由于以下解释,这是我认为最好的答案: However, it's different to other languages in that it returns the result of the last value that halted the execution, instead of a true, or false value.
2021-03-29 00:24:17
@mastazi 是的,恕我直言,它应该以粗体显示。
2021-04-01 00:24:17
应该是答案,它显示了在测试用例中选择的值。
2021-04-08 00:24:17

Javascript 变量没有类型化,因此即使 f 是通过布尔运算符分配的,也可以为其分配整数值。

f 被分配了不等价于 false的最接近的值所以0、false、null、undefined,都被传递过去了:

alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
赞成指出f is assigned the NEAREST value这里非常重要的一点。
2021-03-16 00:24:17
@devios1 但4最近
2021-03-24 00:24:17
“最近”并不完全正确,尽管它确实具有这种外观。作为布尔||运算符的布尔运算符有两个操作数:左侧和右侧。如果 的左侧||,则操作解析为左侧,而忽略右侧。如果左侧为falsy,则解析为右侧。所以null || undefined || 4 || 0实际上解析到undefined || 4 || 0哪个解析到4 || 0哪个解析到4
2021-03-25 00:24:17
不要忘记''在这种情况下也等于假。
2021-03-26 00:24:17

它没有任何魔法。像这样的布尔表达式a || b || c || d被惰性求值。Interpeter 寻找 的值a,它是未定义的所以它是假的所以它继续前进,然后它看到b哪个是空的,它仍然给出错误的结果所以它继续前进,然后它看到c- 同样的故事。最后它看到d并说'嗯,它不是空的,所以我有我的结果',并将它分配给最终变量。

这个技巧适用于所有对布尔表达式进行惰性短路评估的动态语言。在静态语言中,它不会编译(类型错误)。在渴望评估布尔表达式的语言中,它将返回逻辑值(即在这种情况下为真)。

一个轻微的修正:||当左侧为假时,运算符总是解析为整个右侧操作数。作为布尔运算符,它只能看到两个输入:左侧和右侧。解析器不会将它们视为一系列术语,因此它在找到第一个真值时实际上不会停止,除非该值也是 another 的左手操作数||
2021-03-10 00:24:17
在漂亮的静态语言 C# 中可以使用 ?? 运算符 á la:对象 f = a ?? ?? C ???? 乙;
2021-03-19 00:24:17
赫兹迈斯特-谢谢!我不知道那个??运算符可以在 C# 中链接并用于惰性求值技术
2021-04-05 00:24:17
正如其他地方所提到的,d无论是否为空/未定义都将分配最后一个
2021-04-07 00:24:17