什么是双管道运算符(||
)?
双管道运算符(||
)是逻辑OR
运算符。在大多数语言中,它的工作方式如下:
- 如果第一个值为
false
,则检查第二个值。如果是true
,则返回true
,如果是false
,则返回false
。
- 如果第一个值是
true
,则true
无论第二个值是什么,它总是返回。
因此,基本上它的工作原理类似于此功能:
function or(x, y) {
if (x) {
return true;
} else if (y) {
return true;
} else {
return false;
}
}
如果您仍然不明白,请查看此表:
| true false
------+---------------
true | true true
false | true false
换句话说,只有两个值都为假时才为假。
JavaScript有何不同?
JavaScript有所不同,因为它是一种松散类型的语言。在这种情况下,这意味着您可以将||
运算符与非布尔值一起使用。尽管没有意义,但是您可以将此运算符与例如函数和对象一起使用:
(function(){}) || {}
那里发生了什么?
如果值不是布尔值,则JavaScript会将隐式转换为boolean。这意味着,如果该值是falsey(例如0
,""
,null
,undefined
(还参见在JavaScript中所有falsey值)),它将被视为false
; 否则将被视为true
。
所以上面的例子应该给出true
,因为空函数是真实的。好吧,事实并非如此。它返回空函数。那是因为JavaScript的||
运算符不像我一开始所写的那样起作用。它的工作方式如下:
- 如果第一个值是falsey,则返回第二个值。
- 如果第一个值是真实的,则返回第一个值。
惊讶吗 实际上,它与传统的||
运算符“兼容” 。它可以写成下面的函数:
function or(x, y) {
if (x) {
return x;
} else {
return y;
}
}
如果您将真实值传递为x
,则返回x
,即真实值。因此,如果您稍后在if
子句中使用它:
(function(x, y) {
var eitherXorY = x || y;
if (eitherXorY) {
console.log("Either x or y is truthy.");
} else {
console.log("Neither x nor y is truthy");
}
}(true/*, undefined*/));
你懂了"Either x or y is truthy."
。
如果x
是假的,那eitherXorY
就是y
。在这种情况下,您将获得"Either x or y is truthy."
if if y
真实的信息。否则你会得到"Neither x nor y is truthy"
。
实际问题
现在,当您知道||
操作员的工作方式时,您可能可以自己弄清楚这x = x || y
意味着什么。如果x
为true,x
则分配给x
,因此实际上什么也没发生;否则y
分配给x
。它通常用于定义函数中的默认参数。但是,它通常被认为是不好的编程习惯,因为它阻止您传递错误的值(不一定是undefined
或null
)作为参数。考虑以下示例:
function badFunction(/* boolean */flagA) {
flagA = flagA || true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
乍一看似乎有效。但是,如果您false
作为flagA
参数传递(由于它是布尔值,即可以是true
或false
),将会发生什么?它将成为true
。在此示例中,无法将设置flagA
为false
。
最好像这样显式检查flagA
is 是否是一个更好的主意undefined
:
function goodFunction(/* boolean */flagA) {
flagA = typeof flagA !== "undefined" ? flagA : true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
尽管时间更长,但它始终有效并且更易于理解。
您还可以将ES6语法用于默认函数参数,但请注意,它在较旧的浏览器(如IE)中不起作用。如果要支持这些浏览器,则应使用Babel转换代码。
另请参见MDN上的逻辑运算符。
falsy
不是JUST,则选择第二个值undefined
。我见过的次数doWeDoIt = doWeDoIt || true
足以让我哭泣。(即doWeDoIt
现在永远不会false
)