本文的目的是为了和大家分享如何从官方文档中获得答案 至于标题中和本文其他的语法也是非常不规范 在平时开发中需要极力避免使用`==`与不必要的类型转化
我先抛出一个例子 大部分人估计会很疑惑 在语言大战中 很多其他语言的人也经常抓住类似的例子来攻击js
但是js作为一个有规范的语言 所有的结果都要遵循规则吧 然后咱就来带大家看看 关于==
语法在es 2017
中的定义
为啥是2017呢 因为本文写的时候最新的标准就是这个版本 ECMAScript® 2017 Language Specification (ECMA-262, 8th edition, June 2017) 但是没有关系啊 我会截图给大家的
首先先看==
的标准 Abstract Equality Comparison
提示一下 文中涉及到的类型 全都是指基本类型 js目前有七大基本类型: Undefined
, Null
, Boolean
, String
, Symbol
, Number
, Object
. 为了和typeof
返回值一致 我就都使用小写了
这个标准其实不复杂 其实也就十几个步骤 中间各种情况 咱画个流程图 文档中x
和y
有先后顺序 咱们这就不管顺序了吧
中间就5个判断 总结一下 可以分为三组 进行区分
- 相同类型直接返回
===
结果 - 非
object
之间undefined
和null
遇见的时候为true
string
number
boolean
两两遇见的时候将转化成number
进行判断- 其他情况返回
false
object
与其他类型之间- 遇到
undefined
和null
, 返回false
- 遇到
boolean
将boolean
转化为number
重新计算 - 其他情况获取
object
原始值进行重新计算
- 遇到
哎 这样就清晰了
啥是对象的原始值? 好了 这又得看另外一个规则了 toPrimitive
一个前置条件: 原始值不能为object
这个规则又是挺麻烦的一个 流程和情况分支也很多 我就总结一下这里用到的规则吧:
- 如果输入值具有名为
Symbol.toPrimitive
的函数, 函数运算结果即为原始值, 如果运算结果不合条件将会报错 - 计算
valueOf
方法的值, 运算结果如果符合条件则即为原始值 - 计算
toString
方法的值, 运算结果如果符合条件则即为原始值 - 如果以上没有获得原始值将报错
所以 这就是最终的答案
整个流程是这样的
1 | ![] == [] // 最初的等式 |
而这个 ![] == ![]
就比较简单 直接是类型强转false == false
即true
[] == []
也比较简单了 因为类型一样 所以返回[] === []
而任何对象除了同一个引用之外不等于其他任何对象 所以答案是false
举一反三
1 | var dEmpty = {} |