鉴于这段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
本身的值。
答案 0 :(得分:195)
有关说明,请参阅short-circuit evaluation。这是实现这些运营商的常用方式;它不是JavaScript独有的。
答案 1 :(得分:168)
这是为了分配默认值,在这种情况下是y
的值,如果x
变量是 falsy 。 / p>
JavaScript中的布尔运算符可以返回操作数,而不像其他语言那样总是布尔结果。
Logical OR运算符(||
)返回第二个操作数的值,如果第一个操作数是假的,否则返回第一个操作数的值。
例如:
"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"
Falsy 值是指在布尔上下文中使用时强制false
的值,它们是0
,null
,undefined
,空字符串,NaN
,当然还有false
。
答案 2 :(得分:141)
Javacript将short-circuit evaluation用于逻辑运算符||
和&&
。 但是,它与其他语言的不同之处在于它返回停止执行的最后一个值的结果,而不是true
或false
值。
以下值在JavaScript中被视为虚假。
""
(空字符串)忽略operator precedence规则并保持简单,以下示例显示哪个值暂停了评估,并作为结果返回。
false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"
前5个值到NaN
是假的,所以它们都是从左到右进行评估,直到它满足第一个真值 - "Hello"
,这使整个表达式成为真,所以任何进一步的事情都会不进行评估,并且由于表达式而返回"Hello"
。同样,在这种情况下:
1 && [] && {} && true && "World" && null && 2010 // null
前5个值都是真实的并得到评估,直到它满足使表达式为假的第一个假值(null
),因此不再评估2010
,{{1}由于表达式而返回。
您给出的示例是利用JavaScript的这个属性来执行赋值。它可以在任何需要在一组值中获得第一个truthy或falsy值的地方使用。下面的代码会将值null
分配给"Hello"
,因为它可以更轻松地分配默认值,而不是执行if-else检查。
b
您可以将下面的示例称为利用此功能,我相信它会使代码更难阅读。
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
。由于在这个例子中它是假的,我们在noNewMessagesText停止并警告newMessagesText
。
答案 3 :(得分:45)
Javascript变量没有输入,所以f可以被赋予一个整数值,即使它是通过布尔运算符赋值的。
f被赋予最接近的值不等于false 。所以0,false,null,undefined都被传递过来:
alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
答案 4 :(得分:29)
没有任何魔力。像a || b || c || d
这样的布尔表达式被懒惰地评估。 Interpeter查找a
的值,它是未定义的,所以它是假的,所以它继续前进,然后它看到b
为空,这仍然给出错误的结果,所以它继续前进,然后它看到{{1 }} - 相同的故事。最后它看到c
并说'嗯,它不是空的,所以我有我的结果'并将它分配给最终变量。
这个技巧适用于对布尔表达式进行惰性短路评估的所有动态语言。在静态语言中,它不会编译(类型错误)。在急于评估布尔表达式的语言中,它将返回逻辑值(在这种情况下为true)。
答案 5 :(得分:9)
这个问题已经收到了好几个答案。
总之,这种技术正在利用语言编译的特性。也就是说,JavaScript"短路"布尔运算符的求值将返回与第一个非假变量值或最后一个变量包含的值相关的值。请参阅Anurag对那些将评估为false的值的解释。
出于几个原因,使用这种技术并不是一种好的做法;但是。
记录功能:现有替代方案可满足此需求,并且在更多语言中保持一致。这将是三元运营商:
()?值1:值2.
使用三元运算符确实需要更多的输入,但它清楚地区分了被评估的布尔表达式和分配的值。此外,它可以链接,因此可以重新创建上面执行的默认分配类型。
var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';
var f = ( a ) ? a :
( b ) ? b :
( c ) ? c :
( d ) ? d :
e;
alert(f); // 4
答案 6 :(得分:5)
返回输出第一个真值。
如果all为false则返回最后一个false值。
实施例: -
null || undefined || false || 0 || 'apple' // Return apple
答案 7 :(得分:4)
它将新变量(z
)设置为x
的值,如果它是“truthy”(非零,有效的对象/数组/函数/它是什么)或{{ 1}}否则。在y
不存在的情况下,这是提供默认值的一种相对常见的方式。
例如,如果你有一个带有可选回调参数的函数,你可以提供一个不执行任何操作的默认回调:
x
答案 8 :(得分:1)
这意味着如果设置了x
,则z
的值将为x
,否则如果设置了y
,则其值将设置为{{ 1}}的价值。
与
相同z
这是可能的,因为JavaScript中的逻辑运算符不返回布尔值,而是返回完成操作所需的最后一个元素的值(在OR语句中,它将是第一个非假值,在AND语句中它将是最后一个)。如果操作失败,则返回if(x)
z = x;
else
z = y;
。
答案 9 :(得分:1)
它被称为短路操作员。
短路评估表示,仅当第一个参数不足以确定表达式的值时,才会执行或计算第二个参数。当OR(||)函数的第一个参数求值为true时,总值必须为true。
它也可以用来设置函数参数的默认值。
function theSameOldFoo(name){
name = name || 'Bar' ;
console.log("My best friend's name is " + name);
}
theSameOldFoo(); // My best friend's name is Bar
theSameOldFoo('Bhaskar'); // My best friend's name is Bhaskar`
答案 10 :(得分:0)
它将评估X,如果X不为空,则为空字符串,或0(逻辑假),然后将其分配给z。如果X为空,即空字符串,或0(逻辑假),则它将y指定给z。
var x = '';
var y = 'bob';
var z = x || y;
alert(z);
输出'bob';
答案 11 :(得分:0)
根据 Bill Higgins的博客帖子; the Javascript logical OR assignment idiom(2007年2月),从v1.2(至少)
开始,这种行为是正确的他还建议另一种用途(引用): “跨浏览器差异的轻量级规范化”
// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;