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的值,如果xvariables是虚假的

JavaScript中的布尔运算符可以返回一个操作数,并不总是像其他语言的布尔结果。

逻辑OR运算符( || )返回第二个操作数的值,如果第一个操作数是虚假的,则返回第一个操作数的值。

例如:

 "foo" || "bar"; // returns "foo" false || "bar"; // returns "bar" 

Falsy值是在布尔上下文中强制为false值,它们是0nullundefined ,一个空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对那些将被评估为错误的值的解释。

使用这种技术不是好的做法,有几个原因。 然而。

  1. 代码可读性:这是使用布尔运算符,如果编译的行为不被理解,那么预期的结果将是一个布尔值。
  2. 稳定性:这是一个使用多种语言编译语言不一致的特性,由于这个特性,它可能成为未来变化的潜在目标。
  3. 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;