前端碎碎念 之 为何[] == ![] ?

『前端碎碎念』系列会记录我平时看书或者看文章遇到的问题,通常都是比较基础可是容易遗忘的知识点,你也可能会在面试中碰到。 我会查阅一些资料并可能加上本身的理解,来记录这些问题。更多文章请前往个人我的博客前端

相似标题中的问题还有不少,例如:git

为何 [ ] == false 而 !![ ] == true github

or面试

[1] == [1] 是true 仍是 false数组

若是对 == 操做符只知其一;不知其二,就很难解答相似的问题。咱们直接开门见山,看看==是如何工做的,这里的难点主要涉及到js中的隐式强制类型转换。spa

判断步骤以下:code

  1. 若是有一个操做数是布尔值,则在比较相等性以前先将其转换为数值----false转换为0,而true转换为1。对象

  2. 若是一个操做数是字符串,另外一个操做数是数值,在比较相等性以前先将字符串转换为数值。blog

  3. 若是一个操做数是对象,另外一个操做数不是,则调用对象的valueOf()方法,若是获得的值不是基本类型值,则基于返回值再调用toString方法(这个过程即ToPrimitive),用获得的基本类型值按照前面的规则进行比较。rem

  4. 若是两个操做数都是对象,则比较他们是否是同一个对象。若是两个操做数指向同一个对象,则相等操做符返回true, 不然返回false。

这两个操做符在进行比较时则要遵循下列规则。

  1. null 和 undefined 是相等的。

  2. 要比较相等性以前,不能将null和undefined转换成其余任何值

  3. 若是有一个操做数是NaN,则相等操做符返回false, 而不相等操做符则返回true, NaN != NaN

我画了一个图来表示这个过程:

roadmap.path

根据上面的步骤,来分析[] == ![] 为何会返回true

[] == ![]

!运算符的优先级大于 ==,因此实际上这里还涉及到!的运算。
这个比较简单!会将后面的值转化为布尔值。即![]变成!Boolean([]), 也就是!true,也就是false。

其实是对比 [] == false;

运用上面的顺序,false是布尔值,因此转化为数值Number(flase), 为0。

对比[] == 0;

知足第三条规则[] 是对象(数组也属于对象),0不是对象。因此ToPrimitive([])是""

对比"" == 0;

知足第二条规则,"" 是字符串,0是数值,对比Number("") == 0, 也就是 0 == 0。

因此得出 [] == ![]

咱们能够用一样的方法对上面提到的两个等式例子进行判断,都能得出结论。虽然过程有点麻烦,可是本质上就是将两边的比较值转化为数值进行比较。读者能够自行尝试实践。

相关文章
相关标签/搜索