Kon*_*cht 7 javascript arrays coercion
我正在努力了解这个代码片段在基本级别上的工作原理
if([] == ![]){
console.log("this evaluates to true");
}
Run Code Online (Sandbox Code Playgroud)
请帮我理解我错在哪里.我的想法:
!
评估==
.ToPrimitive
调用Next 并[]
转换为空字符串.!
操作员注意到它需要转换""
成boolean
所以它接受该值并使其成为false
然后否定true
.==
喜欢比较数字,所以在我的思考中true
,1
并将[]
其转换为""
然后0
为什么它会起作用呢?我在哪里弄错了?
Jon*_*lms 12
为什么它会起作用呢?
TLDR:
[] == ![]
//toBoolean [1]
[] == !true
[] == false
//loose equality round one [2]
//toPrimitive([]); toNumber(false) [3]
"" == 0
//loose equality round two
//toNumber("") [4]
0 === 0
true
Run Code Online (Sandbox Code Playgroud)
一些解释:
1)
首先是运算符优先级,所以先
!
评估==
否定的东西首先将内部toBoolean
方法调用到"某事"上.在这种情况下,这是一个对象(因为数组是对象),为此它总是返回true
,然后被否定.
2)
现在它取决于松散的平等特殊行为(更多信息请参阅金牛座答案):
如果A是对象(数组是对象)而B是布尔值,它将执行:
ToPrimitive(A) == ToNumber(B)
Run Code Online (Sandbox Code Playgroud)
3)
toPrimitive([])
Run Code Online (Sandbox Code Playgroud)
ToPrimitive(A)尝试通过在A上调用A.toString和A.valueOf方法的不同序列来尝试将其Object参数转换为原始值.
将数组转换为其原语是通过调用toString
(因为它们没有valueOf
方法)来完成的join(",")
.
toNumber(false)
Run Code Online (Sandbox Code Playgroud)
如果参数为真,则结果为1.如果参数为false,则结果为+0.参考
所以false
转换为+0
4)
toNumber("")
Run Code Online (Sandbox Code Playgroud)
StringNumericLiteral为空或仅包含空格将转换为+0.
所以最后""
转换为+0
我在哪里弄错了?
在第1步.否定某事不会打电话,toPrimitive
但toBoolean
......
接受的答案是不正确的(尽管现在是这样),请看这个例子:
if([5] == true) {
console.log("hello");
}
Run Code Online (Sandbox Code Playgroud)
如果所有内容都确实按照接受的答案状态进行处理,那么[5] == true
应该进行评估,true
因为数组[5]
将被转换为其字符串对齐方式("5"
),并且字符串"5"
是真实的(Boolean("5") === true
是true
),所以true == true
必须为真.
但显然情况并非如此,因为条件不会评估true
.
所以,实际发生的是:
1. ![]
将其操作数转换为布尔值,然后翻转该布尔值,每个对象都是真实的,所以![]
要评估为false
.
在这一点上,比较变为 [] == false
2.然后发挥作用的是这两条规则,在抽象平等比较算法的规范中#6中明确说明:
- 如果Type(x)是boolean,则返回比较结果ToNumber(x)== y.
- 如果Type(y)是boolean,则返回比较结果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
is true
).
此时,比较变为0 == 0
.
5.最后,这条规则将适用:
如果Type(x)与Type(y)相同,那么
.........
如果Type(x)是Number,那么
.........
如果x是相同的Number值y,返回true.
而且,这就是比较评估的原因true
.您还可以将这些规则应用于我的第一个示例,以了解它未评估的原因true
.
所有我上面引述的规则明确指出这里的规格.