我正在努力了解这个代码段如何在基本级别上运作
if([] == ![]){
console.log("this evaluates to true");
}
请帮助我理解我错在哪里。我的想法:
!
在==
之前进行评估。ToPrimitive
,[]
转换为空字符串。!
运营商注意到它需要将""
转换为boolean
,因此它会将该值转换为false
,然后否定为true
。< / LI>
==
更喜欢比较数字,所以在我的思考中true
使1
和[]
转换为""
然后0
为什么它会起作用?我在哪里弄错了?
答案 0 :(得分:12)
为什么它会起作用?
TLDR:
.Select(match => string.Concat(...))
.ToArray();
一些解释:
1)
首先有运算符优先级,因此
之前进行评估[] == ![] //toBoolean [1] [] == !true [] == false //loose equality round one [2] //toPrimitive([]); toNumber(false) [3] "" == 0 //loose equality round two //toNumber("") [4] 0 === 0 true
在!
Negating something首先将内部toBoolean
方法调用到“某事”上。在这种情况下,这是一个Object(因为Arrays是Objects),为此它总是返回==
,然后被否定。
2)
现在由loose equalities special behaviour决定(有关更多信息,请参阅金牛座答案):
如果A是对象(数组是对象)而B是布尔值,它将执行:
true
3)
ToPrimitive(A) == ToNumber(B)
ToPrimitive(A)尝试通过在A上调用A.toString和A.valueOf方法的不同序列,将其Object参数转换为原始值。
将数组转换为原语是通过调用 toPrimitive([])
(因为它们没有toString
方法)完成的,基本上是valueOf
。
join(",")
如果参数为true,则结果为1。如果参数为false,则结果为+0。 Reference
因此toNumber(false)
转换为false
4)
+0
StringNumericLiteral为空或仅包含空格,将转换为+0。
所以最后toNumber("")
转换为""
我在哪里弄错了?
在第1步。否定某些内容不会调用+0
,而是toPrimitive
...
答案 1 :(得分:5)
接受的答案不正确(不过现在是这样),请看这个例子:
if([5] == true) {
console.log("hello");
}
如果确实按照接受的答案处理了所有内容,则[5] == true
应该已评估为true
,因为数组[5]
将转换为其字符串副本"5"
),字符串"5"
是真实的(Boolean("5") === true
是true
),因此true == true
必须为真。
但显然并非如此,因为条件不会评估为true
。
所以,实际发生的是:
1。 ![]
会将其操作数转换为布尔值,然后翻转该布尔值,每个对象都是真实的,因此![]
将评估为false
。
此时,比较变为[] == false
2。然后开始发挥作用的是这两条规则,#{3}}在#6中的抽象等效比较算法的规范中:
- 如果Type(x)是boolean,则返回比较结果ToNumber(x)== y。
- 如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)
醇>
此时,比较变为[] == 0
。
3。然后,就是这条规则:
如果Type(x)是Object而Type(y)是String或Number, 返回比较结果ToPrimitive(x)== y。
正如@Jonas_W所述,数组的ToPrimitive
将调用其toString
,它将返回以逗号分隔的内容列表(我过于简单化)。
此时,比较变为"" == 0
。
4。最后(好吧,差不多),这个规则:
如果Type(x)是String而Type(y)是Number, 返回比较结果ToNumber(x)== y。
转换为数字的空字符串为0
(Number("") == 0
为true
)。
此时,比较变为0 == 0
。
5. 最后,此规则适用:
如果Type(x)与Type(y)相同,那么
.........
如果Type(x)是Number,那么
......... 如果x与y的Number值相同,则返回true。
而且,这就是比较评估为true
的原因。您还可以将这些规则应用于我的第一个示例,以了解它未评估为true
的原因。
我在上面引用的所有规则都在规范中明确说明clearly stated。
答案 2 :(得分:0)
首先,要意识到您正在比较两种不同类型的值。 当你使用![]时会导致错误。你有代码(在核心它产生了这个):
if([] == false)
现在是第二部分:因为两个值都是不同的类型而你正在使用&#34; ==&#34;,javascript会将两种值类型转换为字符串(以确保它们具有相同的类型)。它从左边开始。
在左边我们有[]。所以javascript在[]上应用toString
函数,结果为false。试试console.log([].toString())
你应该在左边作为字符串值得到假。在右边我们有布尔值false,而javascript对它做同样的事情。
它也在false上使用toString
函数,这会导致字符串值为false。
试试console.log(false.toString())
这涉及两个核心概念:&#34; ==&#34; &#34; ==&#34;的作品和相关性operator - 无论是从左侧还是右侧开始。
关联性是指调用哪个运算符函数:从左到右或从右到左。 运营商喜欢==或!或+是使用前缀表示法的函数! 如果您使用&#34; ===&#34;,则上述if语句将导致false。 我希望有所帮助。