我们都知道javascript在测试相等性时会做出时髦的转换,但是在引擎盖下究竟发生了什么?如果[0] == 0和0 == [[0]]都为真,为什么[0] == [[0]]为false?
> [0] == 0
true
> 0 == [[0]]
true
> [0] == [[0]]
false
是的,我很期待从==运算符的传递性。
我们都知道javascript在测试相等性时会做出时髦的转换,但是在引擎盖下究竟发生了什么?如果[0] == 0和0 == [[0]]都为真,为什么[0] == [[0]]为false?
> [0] == 0
true
> 0 == [[0]]
true
> [0] == [[0]]
false
是的,我很期待从==运算符的传递性。
[0] == 0
和0 == [[0]]
将原始值与对象进行比较,因此将执行类型转换。在两种情况下,[0]
和[[0]]
最终都将转换为原始值0
。
这在步骤中定义8(和图9)的The Abstract Equality Comparison Algorithm:
- 如果Type(x)是String或数目和类型(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
上@KooiInc的answer在a comment提到@JanDvorak,背后场景,JS不使用toString
进行此转换。然而,在概念上这是发生了什么。
行为是作为每JavaScript的The Abstract Equality Comparison Algorithm
匹配的算法中案例9:类型(X )是对象和类型(y)是字符串 或数字
结果:ToPrimitive(x)== y。即 '0' == 0,因此真
匹配算法的案例8:如果类型(x)是字符串或数字,类型(y)是对象,则 结果:x == ToPrimitive(y)。即,0 == '0',因此真
匹配算法的案例1:类型(x)与类型(y)相同, 如果类型为'object',如果x和y指的是同一个对象,则返回true。否则,返回false。 即参考将匹配,因此虚假
“是的,我期望从==操作符的传递性是天真的。” - 确实。有很多例子 –
只是一个侧面说明,也读这个:http://stackoverflow.com/questions/7202157/why-is-10这帮助了我很多理解为什么这些条件是真的,假的,1, 0或其他。 – briosheje
相关:http://stackoverflow.com/q/22231191/1048572 – Bergi