Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

为什么[] == ![] ? #34

Open
fwon opened this issue Mar 1, 2017 · 0 comments
Open

为什么[] == ![] ? #34

fwon opened this issue Mar 1, 2017 · 0 comments

Comments

@fwon
Copy link
Owner

fwon commented Mar 1, 2017

类似标题中的问题还有很多,例如:

**为什么 [ ] == false 而 !![ ] == true **?

or

[1] == [1] 是true 还是 false

如果对 == 操作符一知半解,就很难解答类似的问题。我们直接开门见山,看看==是如何工作的,这里的难点主要涉及到js中的隐式强制类型转换。

判断步骤如下:

  1. 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值----false转换为0,而true转换为1。
  2. 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值。
  3. 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,如果得到的值不是基本类型值,则基于返回值再调用toString方法(这个过程即ToPrimitive),用得到的基本类型值按照前面的规则进行比较。
  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

所以得出 [] == ![]

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant