以下只是一个理论上的JavaScript问题。我很好奇以下是否可以转换为单一声明:
if(!window.foo){
window.foo = [];
}
window.foo.push('bar');
每个人都可能以前写过这段代码,但可以在一行中完成吗?
起初我觉得这样的事情会起作用:
(window.foo || window.foo = []).push('bar');
但由于分配无效,这不起作用。接下来我尝试在推送上链接某些内容,但这不起作用,因为push不会返回数组。
是否可以在普通的JavaScript中完成任何想法?
(结果应该是window.foo = ['bar']
)
答案 0 :(得分:63)
你的任务落后了*。它应该是:
(window.foo = window.foo || []).push('bar');
JavaScript 中的||
运算符不返回布尔值。如果左侧是真的,它会返回左侧,否则它会返回右侧。
a = a || [];
相当于
a = a ? a : [];
所以写上述内容的另一种方法是:
(window.foo = window.foo ? window.foo : []).push('bar');
*请参阅评论以了解详情
答案 1 :(得分:12)
如果您添加括号以使其符合您的预期,您的代码就可以正常工作:
(window.foo || (window.foo = [])).push('bar');
没有括号,它认为它应首先评估window.foo || window.foo
,然后将数组分配给结果,这是不可能的。
答案 2 :(得分: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