JavaScript中的Ruby's ||= (or equals)是什么?

139

我喜欢 Ruby 的 ||= 机制。如果变量不存在或为 nil,则创建变量并将其设置为某个值:

amount # is nil
amount ||= 0 # is 0
amount ||= 5 # is 0

我现在需要在JavaScript中做类似的事情。该怎么做才符合约定或正确的方式? 我知道||=不是有效的语法。 处理它的两种明显方法是:

window.myLib = window.myLib || {};

// or

if (!window.myLib)
  window.myLib = {};
8个回答

159

两种方法都是正确的,但是如果你正在寻找类似于Ruby中的||=操作符的功能。第一种方法,即variable = variable || {}是你要寻找的方法 :)


4
如果 x 的有效值为假值,例如 false,并且您只想在 x 未定义时设置默认值,请小心使用此功能。 - Joshua Pinter
1
@AshwinKumarS 或者只需使用amount ??= 5; - Sebastian Simon
2
@AshwinKumarS 是的,它可以。请参阅文档规范提案 - Sebastian Simon
@user4642212 很有趣,我尝试在文档页面运行演示,但出现了错误 Error: Unexpected token '=' - AshwinKumarS
@AshwinKumarS 文档链接包含一个浏览器兼容性表格。 - Sebastian Simon
显示剩余3条评论

22
你可以使用逻辑 OR 运算符 ||,如果lVal是一个假值,则评估其右操作数。
假值包括例如null、false、0、""、undefined、NaN
x = x || 1

如果 x 的值是假的(如 false),并且您只想在 x 未定义时设置默认值,请小心使用此功能。 - Joshua Pinter

11

8
更新:该提案现已完成,即已达到第四阶段,并包含在ECMAScript规范的最新草案中。它将被包含在下一个标准中,该标准将于2021年发布。 - Rory O'Kane
2
我们现在生活在未来。答案应该更新 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment 或者我猜浏览页面下方,有人已经添加了其他答案。 - plswork04

5
截至2021年,只要你进行转译或不关心Opera/IE浏览器,你可以使用||=并获得与Ruby相同的行为。
除了Opera和IE外,逻辑或赋值运算符||=现已在所有主要浏览器上原生支持。可以在当前caniuse矩阵MDN参考文档中查看。
TypeScript在4.0版中添加了对该操作符的支持。如果需要支持IE/Opera,则可以使用Babel插件进行转译以实现广泛的兼容性。

5
如果你正在使用对象,你可以使用解构(自ES6以来)如下所示:
({ myLib: window.myLib = {} } = window);

...但是除了混淆之外,您不会获得任何优势。


1
"但是除了混淆之外,您不会获得任何比已接受答案更好的东西" -- 很好 :) - lindes
1
我敢打赌,有人会把这个当作讨厌 JavaScript 的理由。 - Volper

4

-1

1
在实践中,a = a || b 的形式似乎更优化。http://jsperf.com/x-or-x-equals-0-vs-x-equals-x-or-0/3 - jchook
啊,酷工具。如果x有一个值并且短路了,它会是什么样子? - chris
我认为在jsperf上teardown需要明确,以便展示短路性能。我的猜测是V8对形式a = a || b有特殊的优化。此测试应该显示这一点。 - jchook
3
FYI,现在看起来任何差异都已经被优化掉了。 - Charles Wood
a || (a = b) 具有正确的语义来推断函数名称。目前正在讨论新提案的 讨论 中。 - Sebastian Simon
更新:https://devblogs.microsoft.com/typescript/announcing-typescript-4-0-beta - chris

-1

您可以在 JavaScript 中仅限整数使用 |= 运算符来实现所需的行为。但是您必须先定义变量。

let a = 0
a |= 100
console.log(a) // 100

对于对象

let o = {}
o.a |= 100
console.log(o) // {a: 100}

对于数组

let arr = []
arr[0] |= 100
console.log(arr) // [100]

问题不在于 ||=。问题中所需的行为与位运算无关。 - Sebastian Simon
修改过了。希望现在有意义了。 - wallgeek

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