创建数组并将其推入一行

mko*_*yak 41 javascript

以下只是一个理论上的JavaScript问题.如果以下内容可以转换为单个语句,我很好奇:

if(!window.foo){
  window.foo = [];
}
window.foo.push('bar');
Run Code Online (Sandbox Code Playgroud)

每个人都可能以前写过这段代码,但可以在一行中完成吗?
起初我觉得这样的事情会起作用:

(window.foo || window.foo = []).push('bar');
Run Code Online (Sandbox Code Playgroud)

但由于作业无效,这不起作用.接下来我尝试在推送上链接某些内容,但这不起作用,因为push不会返回数组.

有关这是否可以在纯JavaScript中完成的任何想法?
(结果顺便说一下window.foo = ['bar'])

zzz*_*Bov 66

你的任务倒退了*.它应该是:

(window.foo = window.foo || []).push('bar');
Run Code Online (Sandbox Code Playgroud)

||JavaScript 的运算符不返回布尔值.如果左侧是真实的,则返回左侧,否则返回右侧.

a = a || [];
Run Code Online (Sandbox Code Playgroud)

相当于

a = a ? a : [];
Run Code Online (Sandbox Code Playgroud)

因此,编写上述内容的另一种方法是:

(window.foo = window.foo ? window.foo : []).push('bar');
Run Code Online (Sandbox Code Playgroud)

*详见评论


kjh*_*hes 17

2021 年更新

@zzzzBov 的有用答案

(window.foo = window.foo || []).push('bar');
Run Code Online (Sandbox Code Playgroud)

可以使用 new||=运算符、逻辑 OR 赋值1进一步简化,

(window.foo ||= []).push('bar');
Run Code Online (Sandbox Code Playgroud)

1请参阅tcs39/proposal-logic-assignment,目前处于第 4阶段,并受到主要浏览器的支持


Guf*_*ffa 14

如果添加括号以使其符合您的预期,您的代码就可以正常运行:

(window.foo || (window.foo = [])).push('bar');
Run Code Online (Sandbox Code Playgroud)

没有括号,它认为它应该window.foo || window.foo首先进行评估,然后将数组分配给结果,这是不可能的.

  • @epascarello 我会同意的。zzzzBov 的答案更好,如果把它写成一行就更好了,但我可以不用暂停就读到这一点——这就是你所习惯的。 (2认同)

Ply*_*ynx 11

这个问题让我玩了不同的乐趣选择.push返回长度而不是原始数组引用太糟糕了,但是对于更短的表达式,有一些可以立即迭代,映射等的东西会很有帮助.

window.foo = (window.foo||[]).concat(['bar']); // always returns array, allowing:
(window.foo = (window.foo||[]).concat(['bar'])).forEach( ... )

(window.foo = window.foo||[]).push('bar'); // always returns length

window.foo && window.foo.push('bar') || (window.foo = ['bar']); // playing around
Run Code Online (Sandbox Code Playgroud)