JavaScript OR(||)variables赋值的解释
鉴于这段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
有人可以向我解释这种技术叫什么(我最好的猜测是在这个问题的标题!)? 以及如何/为什么它的工作原理?
我的理解是variablesf
将被赋予第一个variables的最接近的值(从左到右),该variables的值不是null或者是undefined,但是我没有设法find关于这个技术的很多参考资料,看到它用了很多。
此外,这种技术特定于JavaScript? 我知道在PHP中做类似的事情会导致f
有一个真正的布尔值,而不是d
本身的值。
请参阅短路评估的说明。 这是实施这些运营商的常用方式; 它不是唯一的JavaScript。
这是为了分配一个默认值 ,在这种情况下是y
的值,如果x
variables是虚假的 。
JavaScript中的布尔运算符可以返回一个操作数,并不总是像其他语言的布尔结果。
逻辑OR运算符( ||
)返回第二个操作数的值,如果第一个操作数是虚假的,则返回第一个操作数的值。
例如:
"foo" || "bar"; // returns "foo" false || "bar"; // returns "bar"
Falsy值是在布尔上下文中强制为false
值,它们是0
, null
, undefined
,一个空string, NaN
,当然也是false
。
Javacript对逻辑运算符||
使用短路评估 和&&
。 但是,与其他语言不同的是,它返回暂停执行的最后一个值的结果,而不是true
值或false
值。
以下值在JavaScript中被认为是虚假的。
- 假
- 空值
-
""
(空string) - 0
- 楠
- 未定义
忽略操作符优先级规则,并且保持简单,以下示例显示哪个值暂停评估,并作为结果返回。
false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"
NaN
的前5个值是虚的,所以他们都从左到右进行评估,直到遇到第一个真值 – "Hello"
,这使得整个expression式成立,所以任何进一步的东西都不会被评估, "Hello"
作为expression的结果返回。 同样,在这种情况下:
1 && [] && {} && true && "World" && null && 2010 // null
前5个值都是真的,并且得到评估,直到遇到第一个虚假值( null
),这使得expression式为false,所以2010
不再被评估,并且由于expression式返回null
。
你给出的例子是利用这个JavaScript属性来执行一个任务。 它可以用于任何需要在一组数值中获得第一个真值或伪值的地方。 下面的代码将赋值"Hello"
给b
,因为它更容易分配一个默认值,而不是执行if-else检查。
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
,否则求值并返回newMessagesText
。 由于在这个例子中是虚伪的,我们在noNewMessagesText中停下来,并提醒"Sorry, you have no new messages."
。
JavaScriptvariables没有input,所以即使已经通过布尔运算符赋值了f,也可以赋给它一个整型值。
f被分配最接近的值, 不等于false 。 所以0,false,null,undefined,全都过去了:
alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'
它没有任何魔力。 布尔expression式像a || b || c || d
a || b || c || d
a || b || c || d
被懒惰地评价。 Interpeter寻找a
的值,它是未定义的,所以它是错误的,所以它继续前进,然后它看到b
是null,这仍然给出错误的结果,所以它继续前进,然后它看到c
– 相同的故事。 最后它看到d
并且说“呵呵,它不是空的,所以我得到了我的结果”,并把它赋值给最终的variables。
这个技巧将适用于对布尔expression式进行懒惰短路评估的所有dynamic语言。 在静态语言中,它不会编译(input错误)。 在渴望评估布尔expression式的语言中,它将返回逻辑值(在这种情况下为true)。
这个问题已经得到了几个很好的答案。
总之,这种技术利用了语言编译的特点。 也就是说,JavaScript将布尔运算符的评估“短路”,并返回与第一个非错误variables值或最后一个variables包含的值相关的值。 请参阅Anurag对那些将被评估为错误的值的解释。
使用这种技术不是好的做法,有几个原因。 然而。
- 代码可读性:这是使用布尔运算符,如果编译的行为不被理解,那么预期的结果将是一个布尔值。
- 稳定性:这是一个使用多种语言编译语言不一致的特性,由于这个特性,它可能成为未来变化的潜在目标。
-
logging的function:有一个现有的替代scheme可以满足这个需求,并且在更多的语言中是一致的。 这将是三元运算符:
()? 值1:值2。
使用三元运算符确实需要多一点打字,但它清楚地区分了正在评估的布尔expression式和正在分配的值。 另外它可以被链接,所以上面执行的默认分配的types可以被重新创build。
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
如果它是“truthy”(非零,一个有效的对象/数组/函数/不pipe它是什么),否则设置新的variables( z
)为x
。 在x
不存在的情况下,这是一种相对常见的方式。
例如,如果你有一个可选的callback参数的函数,你可以提供一个默认的callback函数,
function doSomething(data, callback) { callback = callback || function() {}; // do stuff with data callback(); // callback will always exist }
返回输出第一个真值 。
如果全部都是假的,则返回最后的假值。
例:-
null || undefined || false || 0 || 'apple' // Return apple
这意味着如果设置了x
,那么z
的值将是x
,否则如果设置了y
,那么它的值将被设置为z
的值。
这是一样的
if(x) z = x; else z = y;
这是可能的,因为JavaScript中的逻辑运算符不返回布尔值,而是完成操作所需的最后一个元素的值(在OR语句中,它是第一个非错误值,在AND语句中,它是最后一个)。 如果操作失败,则返回false
。
它将评估X,如果X不为空,则为空string或0(逻辑错误),则将其分配给z。 如果X为空,空string或0(逻辑false),那么它将把y赋给z。
var x = ''; var y = 'bob'; var z = x || y; alert(z);
会输出'bob';
根据比尔·希金斯的博客文章; Javascript逻辑OR分配习惯用法 (2007年2月),这个行为在v1.2(至less)
他还build议另一种用法(引用):“ 跨浏览器差异的轻量级规范化 ”
// determine upon which element a Javascript event (e) occurred var target = /*w3c*/ e.target || /*IE*/ e.srcElement;