短路评估未定义?

时间:2014-02-11 03:35:49

标签: javascript

我正在使用短路评估来设置对象中的密钥。例如:

var obj = {foo : 'bar'}
var obj2 = {}

obj2.somekey = obj.baz || obj.foo //will assign 'bar' to obj2.somekey

与上面代码的唯一区别在于,如果obj.baz不存在,我希望obj.somekey保持未定义,而不是分配obj.foo。我试过了obj2.somekey = obj.baz ||,但它给我一个语法错误。

请注意nullundefinedthis question建议,实际上也不是未定义的。

那么有什么方法可以用短路语法来做到这一点吗?

2 个答案:

答案 0 :(得分:2)

似乎最简单的解决方案是:

obj2.somekey = obj.baz;

但是如果你真的想要logical operator的语义(即空字符串,null0NaNfalse,那么所有评价为false以及||返回右侧的内容),请使用void

obj2.somekey = obj.baz || void(0);

请注意,在这种情况下,将分配属性.somekey,但分配给它的值可能为undefined。有关完整说明,请参阅Felix Kling's excellent answer。要保留属性.somekey本身未定义,只需使用:

if ('baz' in obj) obj2.somekey = obj.baz;

或者即使.somekey为假,也要保留.baz未定义,请使用:

if (obj.baz) obj2.somekey = obj.baz;

答案 1 :(得分:2)

  

我希望obj.somekey保持未定义。

只是要明确:未定义的属性(我的意思是“它不存在”)和值为undefined的属性之间存在差异。无论你做什么,如果你写

obj.somekey = ...;

该属性将被创建,并将在for...in循环中显示。例如。

如果您确实只想在其他属性存在时创建属性,则必须使用if语句:

if (obj.baz) {
   obj.somekey = obj.baz;
}

或稍差的可读形式* * *:

obj.baz && (obj.somekey = obj.baz)

由于短路,只有在左手操作数评估为真时才会评估右手操作数。


* 我个人提倡反对这种风格,因为它使用AND运算符来产生副作用,并且对返回值没有任何作用。 必须使用此样式的情况,因为您被迫使用表达式,可能非常罕见。