Javascript +;!!if语句中的运算符

Javascript +;!!if语句中的运算符,javascript,Javascript,我正在审查angularjs工厂的代码,以便更好地理解它是如何工作的。代码包含一个我不完全理解的if语句 在plnkr演示中,作者写道: if ((+!!config.template) + (+!!config.templateUrl) !== 1) { throw new Error('Expected modal to have exactly one of either `template` or `templateUrl`'); } 显然,通过错误消息,它正在检查这两个选项中是

我正在审查angularjs工厂的代码,以便更好地理解它是如何工作的。代码包含一个我不完全理解的
if
语句

在plnkr演示中,作者写道:

if ((+!!config.template) + (+!!config.templateUrl) !== 1) {
  throw new Error('Expected modal to have exactly one of either `template` or `templateUrl`');
}

显然,通过错误消息,它正在检查这两个选项中是否存在一个。我只是不确定它是如何得出结论的。我找不到有关
^
+的任何信息


我的问题是:这个if语句是如何工作的?(
^
+!
+!!
特别是)

这是一种非常不可读的方法,可以写出变量的布尔值,然后使用一元转换将其转换为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(
)操作符

一元转换:一元加号尝试转换为整数
Number()
也是有效的转换。

+
然后将该布尔值转换为一个数字,对于
true
1
,对于false为
0

> +true
1
> +false
0
就我个人而言,在处理两个布尔人的问题时,我觉得这样写更清楚:

if (!config.template == !config.templateUrl) {
  throw ...
}

显然,代码的清晰性和可读性都很糟糕。

同时,^是按位异或运算符

当处理小于2的数时,<>代码> ^ < /C> >如果你考虑<代码> 0 > />代码>=代码> false < /代码>和<代码> 1 > />代码>=代码>真< /代码>,

是逻辑非运算符。它是一个一元运算符,将其操作数转换为布尔值,然后对其求反<代码>
只是该操作符的两次,第二次
撤消求反,因此最终结果只是转换为布尔值

是一元加号运算符,用于将其操作数转换为数字。对于布尔值,false变为
0
,true变为
1

所以,
+!!(表达式)
如果表达式为真,则计算结果为
1
;如果表达式为假,则计算结果为
0

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) {
尽管有这两个属性的内容

+!!根据布尔值,使用隐式转换将值强制转换为0或1

在很大程度上,这是为了检查是否存在。例如,一个空字符串为false(
!!“”===false
),因此未定义,还有许多其他字符串。这是主要的两个

错误的转换

+!!""        ===   0
+!!false     ===   0
+!!0         ===   0
+!!undefined ===   0
+!!null      ===   0
+!!NaN       ===   0
+!!1         ===   1
+!!true      ===   1
+!!"Foo"     ===   1
+!!3.14      ===   1
+!![]        ===   1
+!!{}        ===   1
“真实”转换

+!!""        ===   0
+!!false     ===   0
+!!0         ===   0
+!!undefined ===   0
+!!null      ===   0
+!!NaN       ===   0
+!!1         ===   1
+!!true      ===   1
+!!"Foo"     ===   1
+!!3.14      ===   1
+!![]        ===   1
+!!{}        ===   1
如果(+!!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)

^是javascript按位异或运算符。
我无法找到有关^or+的任何信息您没有使用正确的关键字。搜索
javascript操作符
,希望这是将简单代码放入代码模糊器的结果,因为人类不可能编写这样的代码。是的,对。是我还是“这个神秘的操作符是什么(实际上只是两个以上的操作符没有空格地粘在一起)”的问题最近出现得更多了?
=两个逻辑not运算符<代码>+
=一元加:;该组合可用于将truthy/falsy条件转换为整数。
Number
在这里是一个合适的替代品,但是
parseInt
在将布尔值转换为数字时不会有用,对吗?我经常听到这样的理由:“这段代码是如此复杂/复杂/重要/无论什么,如果你不知道如何像手背一样解析这些运算符,你就不应该再处理这段代码了。”但老实说,我听到的只是“让我们让这段极其复杂的代码更难解析!”!“不正确。
parseInt(!!.x)
+!!.x
不同。前者是
NaN
。除了正确性之外,我不确定可怕的可读性原理是什么。
+.x
是成功的和明确的。(尽管表达式作为一个整体可以简化为Matt指出的。)请注意,如果这两个确实是布尔值,那么您也可以编写
if(config.template==config.templateUrl){}
…但是,其中一个或两个可能是字符串,而另一个可能是
未定义的
null
,这就是为什么
运算符起作用。如果(模板和模板URL)抛出新错误(“看到模板和templateUrl;您实际上想使用哪一个?”);如果(!template&&!templateUrl)抛出新错误(“既没有看到模板也没有模板URL,我没有任何东西要渲染!”);
我个人不喜欢
+!!
,但值得注意的是,它将扩展到“预期正好指定{3件事情}中的1件”“更干净。在我看来,最具可读性的应该是
if(truthyCount(item1,item2,item3)!==1)
@torazaburo我很确定它是正确的。。。在XOR的周围有一个外部的否定。我的大脑放屁了吗?@torazaburo我可以展示我的工作:对于布尔人
A
B
(A异或B)
(A!=B)
相同。因此
!(A或B)
相当于
!(A!=B)
或者更简单地说,
A==B
。就个人而言,我认为独家or版本(来自OP)是mos