JavaScript 中「相等运算符」和「严格相等运算符」的规则和关系
引言
首先我们抛出两个问题:
为什么
[1] == [1]为false?为什么
[1] == 1为true?
知识点
如果我们要解决上面的疑问,就需要先搞懂 == 和 === 的规则和关系
=== 判断规则:
如果 类型 不同,就 不相等
如果两个值都是 数值 ,并且是同一个值,那么 相等 ( ! 例外)
如果两个值都是 字符串 ,每个位置的字符都一样,那么 相等 ,否则 不相等 。
如果两个值都是 true ,或者都是 false ,那么 相等 。
如果两个值都是 对象 ,且都引用自 同一个 对象或函数,那么 相等 ,否则 不相等 。
如果两个值都是 null ,或者都是 undefined ,那么 相等 。
如果其中至少有一个是 NaN ,那么 不相等 。
== 判断规则:
如果两个值 类型 相同,进行 === 比较。
如果两个值 类型 不同,他们可能相等。根据下面规则进行类型转换再比较:
如果一个是 null 、一个是 undefined ,那么 相等 。
如果一个是 字符串 ,一个是 数值 ,把 字符串转换成数值 后再进行比较。
如果任一值是 true ,把它转换成 1 再比较;如果任一值是 false ,把它转换成 0 再比较。
如果一个是 对象 ,另一个是 数值或字符串 ,把 对象转换成基础类型 的值再比较。对象转换成基础类型在第 2 点有提到。
任何其他组合,都 不相等 。
总结规则
总的来说就是:
对于 === 来说有如下对比规则
不同类型的值
如果两个值的类型不同,直接返回
false。同一类型的原始类型值
同一类型的原始类型的值(数值、字符串、布尔值)比较时,值相同就返回
true,值不同就返回false。需要注意的是,
NaN与任何值都不相等(包括自身)。另外,正0 等于 负0。同一类型的复合类型值
同一类型的复合类型的值(对象、数组、函数)比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个对象( 是否为同一引用 )。
undefined 和 null
undefined和null与自身严格相等,但是两者不严格相等。
对于 == 来说有如下对比规则
原始类型的值
原始类型的数据会转换成数值( Number )类型再进行比较。
对象与原始类型值比较
如果运算子是对象,会转为原始类型的值,再进行比较。
「对象」转换成「原始类型」的值,算法是先调用
valueOf()方法;如果返回的还不是原始类型,再接着调用toString()方法,得到原始类型,如果都得不到原始类型,则报错。得到原始类型后,按上方的第一点「原始类型的值」进行比较。
undefined 和 null
undefined和null与其他类型的值比较时,结果都为false,它们互相比较时结果为true,因为都表示「无」,但两者不「严格相等」,因为本质上还是不一样的,一个是未定义,一个是空。
解决问题
回到第一个问题
为什么
[1] == [1]为false?
答:因为这两个 Array 对象不属于同一个 引用对象 ,所以,这两个数组之间的比较结果为 false 。
- 为什么
[1] == 1为true?
这是因为 [1] 在和 1 进行比较的时候,首先会被转成数字类型,而转成数字类型在实现上又是通过 new Number() 来完成的。
所以,[1] == 1 会变成 Number([1]) == 1 。
同时,Number 方法接受一个 字符串 作为参数的,也就是 [1].toString() === '1',所以 Number([1]) 相当于写 Number('1'),于是很显然 Number([1]) 就是 1 了。
总结
个人总结:对于相等运算符 == 如果一边是对象,一边是基本类型,JavaScript 会先将对象使用抽象操作 ToPrimitive 将对象转换成基本类型 ( Primitive ) 之后再进行比较,之后就是基本类型之间的比较了。
一个对象转化为基本类型的步骤如下:
- 先调用该对象的
valueOf()方法,如果返回值为基本类型,这个值就是最终值。- 否则,继续调用对象的
toString()方法,如果返回值为基本类型,这个值就是最终值。- 都无法得到结果的话,抛出异常
Error: Cannot convert object to primitive value。
注意:如果对象是 Date 实例,则先执行 toString() 方法
转换为基本类型后,再继续转换为同样类型,之后就是对其进行严格相等运算符 === 的操作啦~
发布时间: 2017-12-03 22:25:48
原始链接: JavaScript 中「相等运算符」和「严格相等运算符」的规则和关系
许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。