JavaScript:为什么[] ==![]?

8
在JavaScript中,我注意到[]==![]的结果是true演示 我不理解这个结果。你能解释一下为什么吗?

2
@zengr:我不知道。对我来说,那看起来是一个完全不同的问题。 - BoltClock
1
@BoltClock:[]在布尔上下文中为真,因此![]为假,之后代码执行[] == false,结果为真。 - Antti Haapala -- Слава Україні
@BoltClock 我同意@Antti的观点。该答案详细描述了如何转换[]! [],回答了这个问题。 - zengr
2
@zengr:这并不意味着它是同一个问题。 - BoltClock
不要将其与 [] !== [] 混淆。 - Oriol
显示剩余2条评论
1个回答

10
[]是一个数组,但![]是一个布尔值。当你使用==比较两个类型不同的对象时,两个对象都应该被转换为可比较的对象(使用ToNumber,参见11.9.3中的第7步)。这就是为什么[] == ![]的结果为true,因为第一个空数组被评估为false

11.9.3抽象相等比较算法

比较x == y,其中x和y是值,产生true或false。此类比较执行如下:

  1. [...]
  2. 如果x是null且y是undefined,则返回true。
  3. 如果x是undefined且y是null,则返回true。
  4. 如果Type(x)是Number且Type(y)是String,则返回比较x == ToNumber(y)的结果。
  5. 如果Type(x)是String且Type(y)是Number,则返回比较ToNumber(x) == y的结果。
  6. 如果Type(x)是Boolean,则返回比较ToNumber(x) == y的结果。
  7. 如果Type(y)是Boolean,则返回比较x == ToNumber(y)的结果。
  8. 如果Type(x)是String或Number且Type(y)是Object,则返回比较x == ToPrimitive(y)的结果。
  9. 如果Type(x)是Object且Type(y)是String或Number,则返回比较ToPrimitive(x) == y的结果。
  10. 返回false。

但是,如果使用严格相等运算符===,则结果为false,因为两种类型不同:

11.9.6 严格相等比较算法

比较 x === y,其中 x 和 y 是值,会产生 true 或 false。这样的比较按以下方式执行:

  1. 如果 Type(x) 与 Type(y) 不同,则返回 false。
  2. 如果 Type(x) 是 Undefined,则返回 true。
  3. 如果 Type(x) 是 Null,则返回 true。
  4. 如果 Type(x) 是 Number,则
    1. 如果 x 是 NaN,则返回 false。
    2. 如果 y 是 NaN,则返回 false。
    3. 如果 x 是与 y 相同的 Number 值,则返回 true。
    4. 如果 x 是 +0,且 y 是 -0,则返回 true。
    5. 如果 x 是 -0,且 y 是 +0,则返回 true。
    6. 否则返回 false。
  5. 如果 Type(x) 是 String,则仅当 x 和 y 完全相同(长度相同,在对应位置上的字符也相同)时,返回 true;否则,返回 false。
  6. 如果 Type(x) 是 Boolean,则仅当 x 和 y 都为 true 或都为 false 时,返回 true;否则,返回 false。
  7. 如果 x 和 y 引用同一对象,则返回 true。否则,返回 false。

请详细说明“转换为可比较的对象。这就是为什么[] ==![]会得出true”的含义。这个答案看起来像是没有证据的猜测。关于编辑:仍然不足。相关部分是11.9.3节。您可以按照定义的步骤得出正确的结论。 - Rob W
@RobW:我注意到了我的错误并删除了错误的等式运算符。花了我一点时间来加载ECMA-262.pdf,我的连接像BASIC一样慢。 - Zeta
@RobW:谢谢,已经收藏了。我也在我的硬盘上保存了一份副本,这应该会很有用。 - Zeta
1
[]==![] 发生的是 []![] 之间的抽象相等比较。请注意,typeof(![])boolean,而 typeof([])object。根据文档:对于 x == y,如果 Type(y) 是 Boolean,则返回比较 x == ToNumber(y) 的结果。![] 的 ToNumber 是 false,其值为 0。因此,可以得出以下结论:[] == 0 []==0 的结果是 true - Jacob George
@kidmenot:显然,周六早上还太早了。我已经修正了我的答案。 - Zeta
需要注意的一点是,数组首先通过ToPrimitive转换为字符串,因此[][""][null][undefined]仍然变成了'',而且'' == 0true。但是,["", ""]变成了,,而,不等于0,因为ToNumber(',')计算结果为NaN - Antti Haapala -- Слава Україні

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接