在2个空数组的松散相等比较中发生了什么

Kon*_*cht 7 javascript arrays coercion

我正在努力了解这个代码片段在基本级别上的工作原理

if([] == ![]){
console.log("this evaluates to true");
}
Run Code Online (Sandbox Code Playgroud)

请帮我理解我错在哪里.我的想法:

  1. 首先是运算符优先级,所以先!评估==.
  2. ToPrimitive调用Next 并[]转换为空字符串.
  3. !操作员注意到它需要转换""boolean所以它接受该值并使其成为false然后否定true.
  4. ==喜欢比较数字,所以在我的思考中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步.否定某事不会打电话,toPrimitivetoBoolean......


dou*_*Ort 5

接受的答案是不正确的(尽管现在是这样),请看这个例子:

if([5] == true) {
console.log("hello");	
}
Run Code Online (Sandbox Code Playgroud)

如果所有内容都确实按照接受的答案状态进行处理,那么[5] == true应该进行评估,true因为数组[5]将被转换为其字符串对齐方式("5"),并且字符串"5"是真实的(Boolean("5") === truetrue),所以true == true必须为真.

但显然情况并非如此,因为条件不会评估true.

所以,实际发生的是:

1. ![]将其操作数转换为布尔值,然后翻转该布尔值,每个对象都是真实的,所以![]要评估为false.

在这一点上,比较变为 [] == false


2.然后发挥作用的是这两条规则,在抽象平等比较算法的规范中#6中明确说明:

  1. 如果Type(x)是boolean,则返回比较结果ToNumber(x)== y.
  2. 如果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("") == 0is true).

此时,比较变为0 == 0.


5.最后,这条规则将适用:

如果Type(x)与Type(y)相同,那么
.........
  如果Type(x)是Number,那么
.........
    如果x是相同的Number值y,返回true.


而且,这就是比较评估的原因true.您还可以将这些规则应用于我的第一个示例,以了解它未评估的原因true.


所有我上面引述的规则明确指出这里的规格.