如果 [0] == 0 和 0 == [[0]] 都为真,则为什么 [0] == [[0]] 为假
If both [0] == 0 and 0 == [[0]] are true than why is [0] == [[0]] false?
我们都知道javascript在测试相等性时会进行时髦的转换,但是在引擎盖下究竟发生了什么?
> [0] == 0
true
> 0 == [[0]]
true
> [0] == [[0]]
false
是的,我天真地期望 == 运算符的传递性。
[0] == 0
和0 == [[0]]
将基元值与对象进行比较,因此将执行类型转换。在这两种情况下,[0]
和 [[0]]
最终都将转换为基元值 0
。
这是在抽象相等比较算法的步骤 8(和 9)中定义的:
- 如果 Type(x) 是字符串或数字,Type(y) 是对象,
返回比较结果 x == ToPrimitive(y)。
但是,[0] === [[0]]
比较两个对象,并且两个不同的对象永远不会相等:
1f. 如果 x 和 y 引用同一对象,则返回 true。否则,返回 false。
下面是一个稍微简单的例子,它证明了松散比较不是传递的:
" " == 0 // true
"'n" == 0 // true
" " == "'n" // false
前两个比较执行类型转换(字符串到数字),最后一个不执行,两个字符串的值不同。
您的前 2 个示例隐式地将数组转换为字符串,然后将其与0
进行比较:
var a = [0].toString(); // "0"
var b = a == 0 // "0" == 0; // true
最后一个示例不强制转换数组,它只是比较数组的标识。显然,这些不匹配,因此返回false
。
在您的示例中,您在其中一些数组中拥有的额外深度层不会产生任何影响:
[0] == [0] // false, they're not the same array.
0 == [[[[0]]]] // true, [[[[0]]]].toString() === "0", "0" == 0
正如@JanDvorak在对@KooiInc答案的评论中提到的,在幕后,JS不使用toString
进行此转换。然而,从概念上讲,这就是正在发生的事情。
行为符合 JavaScript 抽象相等比较算法
- 比较 [0] == 0 - 操作数类型不同
匹配算法的情况 9:Type(x) 是对象,Type(y) 是字符串 或数字
结果: ToPrimitive(x) == y. 即 '0' == 0, 因此为 true
- 比较 0 == [[0]] - 操作数类型不同
匹配算法的大小写 8:如果 Type(x) 是字符串或数字,而 Type(y) 是对象, 结果: x == 到基元(y)。即 0 == '0',因此为真
- 比较 [0] == [[0]] - 操作数类型相同,即对象
匹配算法的情况 1:类型(x) 与类型(y) 相同, 如果类型为"对象" 如果 x 和 y 引用同一对象,则返回 true。否则,返回 false。 即引用将被匹配,因此为 false
- React.isValidElement为假阴性
- 为什么为我的数据表设置类没有任何作用
- Javascript逻辑运算符||将0读取为假值.有什么好办法解决这个问题吗
- 为什么 0 === -0 为真,但 1/0 === 1/-0 为假
- Javascript:检查window.fullScreen是否为假,然后在新窗口中全屏打开url
- 多个函数,返回为假但表单仍在提交
- 为什么提交带有 if 条件的表单为假
- 使正数的计算结果为真,使负数计算为假
- 当 Django 中的确认消息为假时,什么都不做
- 如果 [0] == 0 和 0 == [[0]] 都为真,则为什么 [0] == [[0]] 为假
- meteor 允许 Collection.insert 仅当特定会话/会话不为假时
- JavaScript 属性删除如果为假,则不删除,如果为真循环
- 如何在 Select2 中设置最大选择长度,而关闭选择为假
- jQuery- 为什么为全局变量赋值在函数中不起作用
- 为假三维动画添加透视
- 如果验证为假,如何不发布表单
- 为什么eem . hasownproperty()为假?
- 为什么我的比较结果为假
- 为什么为空>3个假和空<3在节点中为true
- 在onclick函数中使用双管道-为什么事件为假