谁能解释为什么这里a = [] ? 1 : 2
a 等于 1 而这里b = [] == true ? 1 : 2
b 等于 2
6 回答
为什么 ('0' ? 'a' : 'b') 的行为与 ('0' == true ? 'a' : 'b')不同。
简而言之:
当您有一个在布尔上下文中评估的值时,它会被传递给以
ToBoolean
转换为布尔值。如果将值与之比较,则会使用 ECMAScript 规范第 11.9.3 节中
==
的算法。在此算法中,两个操作数都转换为字符串或数字,并比较这些值。
更详细的解释
a = [] ? 1 : 2
通过调用将条件转换为布尔值ToBoolean(GetValue(lref))
。现在我假设对于对象,GetValue
只返回对象本身并且所有对象的计算结果为true
.
由于数组只是对象,因此该表达式的结果是1
.
b = [] == true ? 1 : 2
如前所述,这里正在进行相当多的类型转换。
首先,true
转换为数字:
7. 如果 Type(y) 为 Boolean,则返回比较结果 x == ToNumber(y)。
所以我们有
[] == 1
然后第 9 步适用:
9. 如果 Type(x) 是 Object 并且 Type(y) 是 String 或 Number,
则返回比较结果 ToPrimitive(x) == y。
这意味着[]
转换为原始值(字符串或数字)。如果您遵循该ToPrimitive
函数(和第 8.12.8 节),您会发现数组通过将其元素与,
. 由于空数组没有元素,结果是一个空字符串。
所以我们最终得到
"" == 1
然后适用第 5 步:
5. 如果 Type(x) 是 String,Type(y) 是 Number,返回比较结果 ToNumber(x) == y。
一个空字符串被转换为0
,因此0 == 1
是false
并且条件运算符返回2
。
因为数组是一个对象,并且当在布尔比较的上下文中评估一个对象时,它是“真实的”,但并不完全正确。
在第一个示例中,数组被转换为一个布尔值,它产生 true,因为它不是 null、未定义、“”、0 或 false。
在第二个示例中,由于等于运算符,您将获得类型转换。来自 mdn:
如果两个操作数的类型不同,JavaScript 会转换操作数,然后应用严格比较。如果任一操作数是数字或布尔值,则尽可能将操作数转换为数字。
在控制台中尝试了以下操作:
Number(true) //gives 1
Number([]) //gives 0
因此,当转换为数字时,它们是不相等的。
在中,如果不是或a = [] ? 1 : 2
则返回。1
[]
null
undefined
在中,如果是,b = [] == true ? 1 : 2
它会返回,但不是,所以它返回。1
[]
true
2
第一个是分配,因此必须达到真实(但不等同于任何东西)。将空等同于真将是错误的。
[]
因为用返回 true初始化数组而[] == true
不是:-)