查阅官方文档的正确姿势


在之前的博文中可能谈到过这个问题:参照官方文档才是解决问题的根本依据。
以一个经典的问题为例,展示一下大致流程。(当然在平时的工作中,很多步骤是可以省略的):

在JavaScript中[] == ![]的结果是什么?

1.要回答这道题,首先应该是明确js中==运算符计算的流程和规则。

ECMAScript官方规范对于== 流程的定义是:

Alt text
即首先对于左右两端的值进行GetValue()操作。

2.再来看GetValue()

Alt text
GetValue 会获取一个子表达式的值(消除掉左值引用),在表达式 [] == ![] 中,[] 的结果就是一个空数组的引用。

3. ![] 按照如下规则

Alt text
执行ToBoolean([])操作。

4.ToBoolean([])根据规则

Alt text
返回true;既满足 “If oldValue is true,return false” 。
所以![]返回false,比较变成[]==false
现在到了12.11.3的第5步。

5.来看Abstract Equality Comparison的规则

Alt text
在这段算法里,匹配条件 7,调用ToNumber(false)进行比较。

6.那么根据ToNumber()的规则

Alt text
所以ToNumber(false) 返回0,于是比较变为[] == 0
在此处因为 [] 是对象,根据7.2.13的规则9,比较ToPrimitive([])==0

7.ToPrimitive (object)规则如下

Alt text

在这一步中hintnumber,所以对应的操作顺序为valueOf,toString直至返回基本数据类型为止。
依次执行[].valueOf()[].toString()。返回空字符串。

所以在7.1.3中我们继续执行Argumengt TypeObject的第二步ToNumber(''),返回0;

0 == 0所以结果为 true

总结

在解决这个问题的过程中,我们明确了ECMAScript中的对于以下规则的定义:

  1. ==
  2. Abstract Equality Comparison
  3. GetValue()
  4. ToBoolean()
  5. ToNumber()
  6. ToPrimitive()
  7. valueOf,toString

有理有据,令人信服。


参考:
ECMA-262 7th Edition

我是王浩然,15年毕业于合肥工业大学,现就职于趣分期。</br>乐于分享,喜欢折腾。