关键词:js 隐式转换
这个问题涉及到 JavaScript 中的类型转换和比较操作的规则。
在 JavaScript 中,[] == ![]
的比较过程如下:
-
![]的计算
!
是逻辑非操作符,它会首先将右侧的操作数转换为布尔值,然后反转该布尔值。对于空数组[]
,在 JavaScript 中,所有对象(包括数组)在布尔上下文中都被认为是true
。因此,![]
首先将[]
转换为true
,然后取反,变成false
。 -
比较
[]
与false
根据 ECMAScript 规范,在进行抽象等值比较(
==
)时,如果比较的两个操作数类型不同,JavaScript 会尝试将它们转换成一个共同的可比较类型。在本例中,一边是对象(空数组[]
),另一边是布尔值false
。规则是,如果有布尔值参与比较,先将布尔值转换为数值再进行比较。布尔值
false
转换为数值0
。 -
比较
[]
与0
现在比较的是对象(空数组
[]
)与数字(0
)。根据规范,当比较对象与数字时,对象会先尝试转换为原始值(通过调用它的valueOf
和(或)toString
方法),用于比较。对于空数组
[]
,[].toString()
结果是""
(空字符串)。 -
比较
""
与0
最后的比较是在空字符串(
""
)与数字0
之间进行。在这个阶段,字符串会被转换为数字,空字符串转换为数字时结果是0
。因此,最终比较的是
0 == 0
,这显然是true
。
因此,[] == ![]
返回true
的原因是,在 JavaScript 中将操作数从对象到布尔值,再到字符串,最后到数字的一系列隐式类型转换导致的。这也展示了 JavaScript 中类型强制转换规则的复杂性和==
运算符可能带来的意外行为。这就是为什么很多 JavaScript 编程风格指南推荐使用===
(严格等于运算符),因为它不会进行类型转换,可以避免这种类型的意外结果。