+! if语句中的运算符

时间:2015-12-28 22:19:38

标签: javascript

我正在审查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语句是如何工作的? (^+!+!!具体)

6 个答案:

答案 0 :(得分:72)

!! converts a value to a boolean (true or false). +然后将该布尔值转换为数字,1true0为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) {

尽管这两个属性的内容。