Js中==的隐式转换逻辑?

为什么[]==![]//true
有优先级么

阅读 3.7k
4 个回答

由我写的这篇文章中: JS中的关系比较与相等比较运算,里面有谈到相等比较运算的规则。

[]==![]的运算步骤为下:

  1. 右值受了逻辑否运算(!)的影响会转为布尔值,跟据ECMAScript标准中的ToBoolean内部运算规定,数组为物件类型,转为true,前面因带了逻辑否运算(!)则反转布尔值,变为false。此运算变为[] == false

  2. 根据标准相等比较演算第(7)规则,Type(y)是Boolean时,进行x == ToNumber(y),右值需经ToNumber内部运算,右值转变为0数字,此运算变为[] == 0

  3. 根据标准相等比较演算第(9)规则(详略),左值此时的数组为对象类型,进行ToPrimitive内部运算,左值得出空字符串"",此运算变为"" == 0

  4. 根据标准相等比较演算第(5)规则(详略),左值此时的空字串符进行ToNumber内部运算,得出0数字。此运算变为0 == 0

  5. 因左值与右值此时为同数据类型,进行严格相等比较演算,依4-b规则,左值与右值为同样数字,最后得出true结果。

以上,最终结果为true

整体运作逻辑就这样,规则里都有排愈前面的愈优先。

注: ToPrimitive的内部运算规则,请参考另一篇我写的文章中有说明: JS的{} + {}与{} + []的结果是什么?

右边的[]转换为布尔型,只有以下六种转换的布尔型时为false,因此[]为true,![]为false

  • null

  • undefined

  • 0

  • NaN

  • ""

  • false

Boolean([]) == true //true

在比较 [] == false 时,两边被转换为数字型,都为0

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

这个问题非常有意思,赞一个。

首先, 如果是比较两个[]的话,正确的写法应该是!==而不是==!

[]==![]相当于[]==(![]),是将后者取非之后再与前者相比。

!写反了看起来似乎也没什么事:

0 == !1 // true
0 !== 1 //true

然而,JavaScript的比较有两种,严格比较非严格比较

  • ==!=非严格比较,这时会进行类型转换然后再比较。

  • =====!严格比较

回到问题:

  • !==严格比较

  • ==!的比较符号事实上是==,因此是非严格比较

[]!==[]为什么为true?

[]是数组,在JavaScript中,数组也是对象,属于引用类型。相当于C语言中的指针。

==!严格比较(strict comparison)。当比较两个对象时,要求指向是同一个对象才相等。

[]!==[]比较的是两个不同对象,因此结果为true。

[]==![]为什么为true?

![]为false,因为空数组的布尔值为true。
[]是数组对象。
[]![]类型不同,根据==比较算法,经过一系列复杂的变换(此处省略一千字)。最后结果为true。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏