JavaScript 数组比较奇怪的行为

标签 javascript arrays equality ecmascript-5

我试图找出为什么 JavaScript 在比较相同的数组时有这种奇怪的行为:

var array = [0];
console.log(array == array); //true
console.log(array == !array); //true?

第一个很容易完成,它们引用同一个对象,但第二个非常棘手,我正在努力理解这个过程。

请注意,我知道这是abstract equality比较与否strict equality比较,并且我知道它们的差异(我知道使用 === 会导致 false 结果,但我试图找出 == 的行为)。

附注:此内容取自 wtfjs.com ,我没有找到解释,所以我尝试自己给出它,并认为它可能“有用”。

最佳答案

第一个相等很简单,它是同一对象(相同引用)之间的比较,因此它返回true

第二个有点棘手,所以我会在下面尝试更好地解释。

TL;DR

对于那些有点懒的人,这里有一个简单的解释,没有在每一步引用规范:

[0] == ![0] => 我们首先评估 ![0],这会产生 false(因为 [0] 是一个真实值)。

[0] == false => [0] 被评估为 [0].toString() ,即 “0”

"0"== false => "0" 转换为数字0;对于 false 也是如此,所以我们得到:

0 == 0 最终为true

完整说明

对于第一个等式,为了完整起见,我在这里引用了规范中感兴趣的部分。

1.f Return true if x and y refer to the same object. Otherwise, return false.

所以这会返回 true,正如预期的那样。现在是棘手的部分:

首先,我们必须计算右侧的UnaryExpression:

  1. expr 为 UnaryExpression 的计算结果。
  2. oldValueToBoolean (GetValue(expr))。
  3. 如果oldValue为true,则返回false
  4. 返回true

但是ToBoolean使用这个algorithm ,并且 GetValue 应返回 Object 或非空 String,因此计算结果为 true 。回到我们的UnaryExpression,我们有!true,所以最终评估的结果是false

所以我们回到了最初的比较,现在我们正在将 ObjectBoolean 进行比较。

7.If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

ToNumber(false)0,所以现在我们正在比较 ObjectNumber

返回规范:

9.If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.

调用ToPrimitive我们的数组应该返回其 [[DefaultValue]],根据 this kangax's answer 应该是这样的,对数组本身调用 toString 的结果,因此我们得到 "0"

因此,回到我们的比较,它已成为 StringNumber 之间的相等性。

5.If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.

调用ToNumber对我们的字符串 "0" 产生 0,我们最终再次进行简单的比较:0 == 0

最终规范步骤:

1.c.iii If x is the same Number value as y, return true.

这里解释了结果。

关于JavaScript 数组比较奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22646968/

相关文章:

javascript - 无法呈现 Google 可视化 ChartWrapper

python - 在 Python 中创建这个 numpy 数组

java - 如何比较 Java 中的字符串?

c++ - 为什么用于字符串比较的 == 运算符相对于任一字符串长度是线性时间(看起来)?

c++ - 如果 operator< 适用于浮点类型,为什么我们不能将它用于相等性测试?

javascript - 为什么 offsetWidth 显示不正确的值?

javascript - 按应用程序模式从扩展程序运行网页或本地页面

javascript - 如何获取canvas的中心点

c++ - 在基于数组的程序中获取最后一个字符串或最后一个价格后,程序崩溃/停止

arrays - 阵列已确定尺寸 - 类模块