2

一:前言

写前端代码的一个避不开的问题:“==” “===”到底是怎么回事?
下面是大众的理解:

1. "=="指的是数值的相等。即使类型不一致,转化后的值相等,还是返回true
2. "==="指的是类型和数值都相等,如果类型不一致就直接呵呵了

然而记住了这些并没有什么用,上面的说法太不具体了,该出错的时候还是会出错。

二:正文

1.“==”是怎么回事?

0 == null 

上面的表达式返回true还是false??

读懂规格上,下面是算法细节。

ReturnIfAbrupt(x).
ReturnIfAbrupt(y).
If Type(x) is the same as Type(y), then
Return the result of performing Strict Equality Comparison x === y.
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
If Type(x) is Number and Type(y) is String,
return the result of the comparison x == ToNumber(y).
If Type(x) is String and Type(y) is Number,
return the result of the comparison ToNumber(x) == y.
If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
If Type(x) is either String, Number, or Symbol and Type(y) is Object, then
return the result of the comparison x == ToPrimitive(y).
If Type(x) is Object and Type(y) is either String, Number, or Symbol, then
return the result of the comparison ToPrimitive(x) == y.
Return false.

上面这段算法,一共有12步,翻译如下。

如果x不是正常值(比如抛出一个错误),中断执行。
如果y不是正常值,中断执行。
如果Type(x)与Type(y)相同,执行严格相等运算x === y。
如果x是null,y是undefined,返回true。
如果x是undefined,y是null,返回true。
如果Type(x)是数值,Type(y)是字符串,返回x == ToNumber(y)的结果。
如果Type(x)是字符串,Type(y)是数值,返回ToNumber(x) == y的结果。
如果Type(x)是布尔值,返回ToNumber(x) == y的结果。
如果Type(y)是布尔值,返回x == ToNumber(y)的结果。
如果Type(x)是字符串或数值或Symbol值,Type(y)是对象,返回x == ToPrimitive(y)的结果。
如果Type(x)是对象,Type(y)是字符串或数值或Symbol值,返回ToPrimitive(x) == y的结果。
返回false。

引用MDN上的一张图就是:

图片描述

由于0的类型是数值,null的类型是Null(这是规格4.3.13小节的规定,是内部Type运算的结果,跟typeof运算符无关)。因此上面的前11步都得不到结果,要到第12步才能得到false。

0 == null // false

上面12条规则,对于“==”部分可以用一张图的总结:

clipboard.png

前面说得很乱,根据我们得到的最终的图3,我们总结一下==运算的规则:

  • undefined == null,结果是true。且它俩与所有其他值比较的结果都是false。
  • String == Boolean,需要两个操作数同时转为Number。
  • String/Boolean == Number,需要String/Boolean转为Number。
  • Object == Primitive,需要Object转为Primitive(具体通过valueOf和toString方法)。

对这张图的详细介绍可以查看文章:https://segmentfault.com/a/11...
2.“===”又是怎么回事?
这个比较简单了,"==="是严格意义上的相等,必须要了类型和值都相等才返回true,否则返回false。所以在判断的时候比较容易就能看出来(一模一样才是true)。

三.扩展延伸

比较是否相等有三种方法:

  1. === 严格的相等
  2. == 宽松的相等
  3. Object.is

一张表格来说明它们之间的区别:

图片描述

这里主要注意 NaN 、 -0 +0这两对表现得不一致情况。

四.附录:常见的引用对象转基本类型的例子

1.对象({}或者非空对象)转基本类型返回"[object Object]"

const obj = {};
obj.toString();//"[object Object]"
obj.name='name';
obj.toString();//"[object Object]"

2.数组转基本类型,返回数组元素合集组成的字符串,每个元素用","连接

[].toString();//""
[1,2].toString();//"1,2"
[[1,2],3].tonString();//"1,2,3"

specialCoder
2.1k 声望167 粉丝

前端 设计 摄影 文学