PHPz2017-04-11 11:30:11
由我写的这篇文章中: JS中的关系比较与相等比较运算,里面有谈到相等比较运算的规则。
[]==![]
的运算步骤为下:
右值受了逻辑否运算(!)的影响会转为布尔值,跟据ECMAScript标准中的ToBoolean内部运算规定,数组为物件类型,转为true
,前面因带了逻辑否运算(!)则反转布尔值,变为false
。此运算变为[] == false
。
根据标准相等比较演算第(7)规则,Type(y)是Boolean时,进行x == ToNumber(y)
,右值需经ToNumber内部运算,右值转变为0
数字,此运算变为[] == 0
根据标准相等比较演算第(9)规则(详略),左值此时的数组为对象类型,进行ToPrimitive内部运算,左值得出空字符串""
,此运算变为"" == 0
根据标准相等比较演算第(5)规则(详略),左值此时的空字串符进行ToNumber内部运算,得出0
数字。此运算变为0 == 0
因左值与右值此时为同数据类型,进行严格相等比较演算,依4-b规则,左值与右值为同样数字,最后得出true
结果。
以上,最终结果为true
。
整体运作逻辑就这样,规则里都有排愈前面的愈优先。
注: ToPrimitive的内部运算规则,请参考另一篇我写的文章中有说明: JS的{} + {}与{} + []的结果是什么?
巴扎黑2017-04-11 11:30:11
右边的[]转换为布尔型,只有以下六种转换的布尔型时为false,因此[]为true,![]为false
null
undefined
0
NaN
""
false
Boolean([]) == true //true
在比较 [] == false 时,两边被转换为数字型,都为0
Number([]) == 0
Number(false) == 0
大家讲道理2017-04-11 11:30:11
这个问题非常有意思,赞一个。
首先, 如果是比较两个[]的话,正确的写法应该是!==而不是==!。
[]==![]相当于[]==(![]),是将后者取非之后再与前者相比。
!写反了看起来似乎也没什么事:
0 == !1 // true
0 !== 1 //true
然而,JavaScript的比较有两种,严格比较和非严格比较。
==与!=是非严格比较,这时会进行类型转换然后再比较。
===与==!是严格比较
回到问题:
!==是严格比较
==!的比较符号事实上是==,因此是非严格比较
[]是数组,在JavaScript中,数组也是对象,属于引用类型。相当于C语言中的指针。
==!是严格比较(strict comparison)。当比较两个对象时,要求指向是同一个对象才相等。
而[]!==[]比较的是两个不同对象,因此结果为true。
![]为false,因为空数组的布尔值为true。
[]是数组对象。
则[]与![]类型不同,根据==比较算法,经过一系列复杂的变换(此处省略一千字)。最后结果为true。