空JavaScript阵列的布尔值冲突

时间:2010-11-19 14:48:55

标签: javascript

任何人都可以解释为什么以下两个陈述都评估为 true

[] == false

!![]

这个问题完全出于好奇,为什么会发生这种情况而不是如何最好地测试数组是否为空。

2 个答案:

答案 0 :(得分:61)

第一个:

[] == false

==运算符确实键入了对其操作数的转换,在这种情况下,双方都转换为Number,Abstract Equality Comparison Algorithm上的步骤将是:

  • object == boolean
  • object == number
  • string == number
  • number == number

在代码中:

[] == false; // convert false to Number
[] == 0;     // convert [] to Primitive (toString/valueOf)
"" == 0;     // convert "" to Number
0  == 0;     // end

第二个比较,[]被转换为原始,它们的valueOftoString方法被执行,但是自从valueOf在Array对象上,返回对象本身(是继承自Object.prototype),然后使用toString方法。

如您所见,两个操作数都转换为Number,两者都为零,例如:

Number([]) == 0;
Number(false) == 0;

当转换为Number时,空数组产生零,因为其字符串表示形式为空字符串:

[].toString(); // ""

一个空字符串转换为Number,产生零:

+""; // 0

现在,双重否定(!![])生成为真,因为所有对象实例都是真实的:

![];  // false, [] is truthy
!![]; // true, negation

falsey 的唯一值是:

  • null
  • undefined
  • 0
  • NaN
  • ""(空字符串)
  • false

转换为布尔值时,其他任何内容都会生成true

另见:

答案 1 :(得分:1)

[] == false

在这种情况下,左侧的类型是对象,右侧的类型是布尔值。当将对象与(==抽象等式比较)布尔值进行比较时,Javascript首先将布尔值转换为数字,得到0.然后它将对象转换为“基元”,产生空字符串“”。接下来,它将空字符串与0进行比较。空字符串转换为数字,产生0,在数字上等于右侧的0,因此整个表达式的结果为真。

价: http://es5.github.com/#x11.9.3 11.9.3抽象等式比较算法

!! []

在这种情况下,Javascript将对象转换为布尔值true,然后将其反转,结果为false。