我正在审查angularjs工厂的代码,以便更好地了解它的工作原理。该代码包含我不完全理解的if
声明。
在plnkr演示中,作者写道:
if ((+!!config.template) + (+!!config.templateUrl) !== 1) {
throw new Error('Expected modal to have exactly one of either `template` or `templateUrl`');
}
It is slightly different in the github repo:
if (!(!config.template ^ !config.templateUrl)) {
throw new Error('Expected modal to have exactly one of either `template` or `templateUrl`');
}
显然,错误消息是检查两者中是否存在其中一个。我不确定结论如何。我无法在^
或+!
我的问题是:这个if语句是如何工作的? (^
或+!
或+!!
具体)
答案 0 :(得分:72)
!!
converts a value to a boolean (true
or false
). +
然后将该布尔值转换为数字,1
为true
或0
为false。
> +true
1
> +false
0
在处理两个布尔值时,我个人觉得写这样的东西更清楚:
if (!config.template == !config.templateUrl) {
throw ...
}
显然,代码清晰度和可读性都很糟糕。
答案 1 :(得分:33)
+!使用隐式转换将值转换为0或1,具体取决于其布尔值
在大多数情况下,这是为了检查是否存在。例如,空字符串为false(!!"" === false
),因此未定义,还有许多其他字符串。那些是主要的两个
<强>&#34; Falsey&#34;转化强>
+!!"" === 0
+!!false === 0
+!!0 === 0
+!!undefined === 0
+!!null === 0
+!!NaN === 0
<强>&#34; Truthy&#34;转化强>
+!!1 === 1
+!!true === 1
+!!"Foo" === 1
+!!3.14 === 1
+!![] === 1
+!!{} === 1
if((+ !! config.template)+(+ !! config.templateUrl)!== 1)
希望这在这一点上更有意义。对象config
有两个我们正在检查的属性。 .template
和.templateUrl
。将使用+!!
隐式强制转换为0或1,然后进行比较以确保它不是1(这意味着它是0或2) - 属性可以打开也可以关闭但是没有什么不同。
这里的真相表如下:
template templateUrl (+!!) + (+!!) !==1
"foo" "foo" 1 + 1 true
undefined undefined 0 + 0 true
undefined "" 0 + 0 true
"" undefined 0 + 0 true
12 "" 1 + 0 false
"" 12 0 + 1 false
undefined "foo" 0 + 1 false
"" "foo" 0 + 1 false
"foo" "" 1 + 0 false
"foo" undefined 1 + 0 false
所有这些的很多更简单的方法就是使用隐式布尔转换
if (!config.template === !config.templateUrl)
答案 2 :(得分:30)
这是一种非常难以理解的方法来写出变量的布尔值,然后使用一元转换将其转换为0/1数字结果。
考虑:
+!!true; //this converts true to false, then to true again, and true is 1 when converted
+!!0; //converts 0 (falsy) to true, then false, and then the numeric 0
从技术上讲,!!
不是它自己的运算符,它只是NOT(!
)运算符两次。
一元转换:ECMA spec doc一元加上尝试转换为整数。 Number()
也是有效的转化。
答案 3 :(得分:6)
同时,^
是按位XOR运算符。
当处理小于2的数字时,如果您考虑^
= ||
和0
=,false
将像布尔OR(1
)一样工作true
。
答案 4 :(得分:6)
!是逻辑非运算符。它是一个一元运算符,它将其操作数转换为布尔值,然后将其否定。 !!
只是那个运算符两次,第二个!
撤消了否定,所以最终结果只是转换为布尔值。
+是一元加号运算符,它将操作数转换为数字。在布尔值的情况下,false变为0
,true变为1
。
因此,如果表达式是真实的,+!!(expression)
评估为1
,如果表达式是假的,则0
评估为factor == 2^32
。
答案 5 :(得分:3)
if ((+!!config.template) + (+!!config.templateUrl) !== 1) {
0 + 0 !== 1 true
0 + 1 !== 1 false
1 + 0 !== 1 false
1 + 1 !== 1 true
等于
if (!config.template === !config.templateUrl) {
尽管这两个属性的内容。