1. 看完这篇,“==”不是问题
    1. 前言
    2. 需要记忆的少量知识
    3. Toprimitive(Object)
    4. 比较特殊的知识点
    5. 什么是空值?
    6. 上述内容的一些解释
    7. 下面让我们来利用上述内容推导结果
    8. 以上内容同样适用于(<)和(>)
    9. 最后

看完这篇,“==”不是问题

前言

此方法的总结起因于《You dont know JS》,在我看到“==”那里的时候,觉得作者只是在罗列ECMA的内容,包括在最后他罗列了二十多个特殊情况,也没有解释为什么会这样?

关于在ECMA的“==”内容我也有去看,上面只写了很少的一部分。大部分的特殊情况比如,“undefined==0”,并没有给出一定的规范。

可能有人觉得平时不怎么用“==”,我为什么要了解它?因为“>”“<”等非等于的比较也存在“==”的行为,并且没有像“===”的语法。

以下方法专注于一条“==”的推导逻辑,并不需要大量记忆,而且一些内容也有着一定的解释,相信大部分有经验的前端程序员都是通过大量经验或记忆来避免“==”的错误,不过在看完下面的内容后,你不再需要这么做。当然,最大受益者是初学者。

以下内容我希望在《You dont know JS》替换掉作者的“==”内容,已经提了issues,但是作者已经三天没有回复了(我看到一些短幅内容已经回复),也不知道看没看。

其实我想等《You dont know JS》的作者回复或者讨论以下再来发布的,太慢了,我已经迫不及待跟大家来讨论了,哈哈!

需要记忆的少量知识

我相信,这个量肯定要比标准的内容还有一些特殊情况要少的多得多。

注意:此处的others表示其它基础类型

左值(x) 右值(y) 隐式处理
string number ToNumber(x)
boolean others ToNumber(x)
Object !Object Toprimitive(x)

Toprimitive(Object)

​ 先返回valueOf()的值,若返回的不是基础类型的值,

​ 则返回toString()的值,若返回的不是基础类型的值,

​ 则抛出异常。

需要注意特殊情况:

  • String对象,上述的转换过程是反过来的。
  • 如果定义了[Symbol.toPrimitive],则此方法优先于前面两个方法。

比较特殊的知识点

  • undefined==null  //true
  • null和undefined单独出现与其他值进行比较不进行转换。

  • 空值情况

    Number("<空值或空值的组合>")===0  //true

什么是空值?

  1. (啥都没有)
  2. (Space空格)
  3. (空格的转义)
  4. (Tab缩进)
  5. \r
  6. \n
  7. \f
  8. \t
  9. 可能还有,我只知道这么多了

掌握以上知识点其实已经完全掌握在”==“的状况下的隐式转换了,接下来是一些解释。

上述内容的一些解释

  • 为什么null和undefined与其他值比较不进行转换

    大家如果了解原型链就会知道null在原型链的顶层,null是没有任何方法的,所以null是不可以进行隐式转换的;而其他的基础类型因为引擎去包装了一层对应的构造函数,所以挂载了toString或toNumber这样的方法,可以进行隐式转换。

    undefined,大家见过undefined()这样的写法吗?没有,所以它也没有构造函数,没有挂载方法,不可以进行隐式转换。

  • 为什么null和undefined双等号相等,三等号不相等

    ECMA标准规定,这点没有规律可循。

下面让我们来利用上述内容推导结果

​ 首先,要纠正一下思维,(==)指可以进行强制类型转换的等于比较,隐式转换只是在双方属于不同类型的时候才会触发,遇到相同类型会直接比较。并且隐式转换具有阶段性,一会我们马上就会遇到。

​ 就从《You dont know JS》来几个特殊的,因为上面作者出版的版本内容上特殊情况没有解释为什么,至于结果,我就不写出来了,自己动手才是王道。

  • “0” == false
左值 右值 解释
“0” false 符合左值为其他基础类型,右值为boolean的情况,右值toNumber
“0” 0 符合左值为string,右值为number的情况,左值toNumber
0 0
  • false == []
左值 右值 解释
false [] 符合左值为非对象,右值为对象的情况,右值toPrimitive,最终是通过toString
false “” 符合左值为boolean,右值为其他基础类型的情况,左值toNumber
0 “” 符合左值为number,右值为string的情况,右值toNumber,并且符合空值情况,转换为0
0 0
  • false == undefined

    符合undefined单独和其他值比较。

以上内容同样适用于(<)和(>)

​ 但是要注意(<=)和(>=),他在引擎中会被处理成不大于和不小于,如:

a<=b    --->    !(a>b)

​ 为什么要说这点?试着输出下面的例子你就明白了

var a= {b:1};
var b= {b:2};

console.log(a>b);  //false
console.log(a==b);  //false
console.log(a>=b);  //true

最后

如果还有什么不理解、想和我交流、发现问题的请下方评论。

我的博客