js中的==和===真的让人感觉非常奇怪,有时候会产生很多错觉。为此就根据《js权威指南》中的介绍详细的解释梳理了一下两者的区别。
==运算符称作“相等运算符”
===运算符称作“严格相等运算符”或者“恒等运算符”
严格相等运算符首先计算其操作数的值,然后比较这两个值,比较过程中,没有任何类型转换:
1.如果两个值类型不相等,则他们不想等。
2.如果其中一个值是NaN,或者两个值都是NaN,则他们不相等。NaN和其他任何值都是不相等的,包括本身。通过NaN!==NaN来判断NaN,只有在x为NaN的时候,这个表达式的值才是true.
3.0 === -0 返回true
4.如果两个值为字符串,且所含的对应位上的16位(注1)完全相等,则他们相等。也可以通过String.localeCompare()来比较字符串
5.如果两个值指向同一个对象则他们是相等的。
相等运算符和严格相等运算符相似,但相等运算符的比较不严格。会进行一些类型转换
1.如果两个操作数类型相等,则和严格相等操作比较规则一样
2.如果一个是null,另一个是undefined则他们相等
3.如果一个值是数字,另一个是字符串,先将字符串转化为数字,然后使用转换后的值进行比较
4.如果其中一个是true,则将其转换为1再进行比较。如果其中一个是false,则将其转换为0再进行比较。
5.如果一个值是对象,另一个是数字或字符串,则先将对象转换为原始值,然后进行比较。对象通过toString()方法或者valueOf()方法转换为原始值,js语言核心的内置类首先尝试使用valueOf(),再尝试使用toString(),除了日期类,日期类只是使用toString()转换。那些不是js语言核心的对象通过各自实现中定义的方法转换为原始值。
6.其他类型都不相等
"1" == true //true
上面的代码布尔值true首先转换为1,然后字符串“1”转换为数字1
0 == null //false
0 == undefined //false
注1:js采用UTF-16编码的Unicode字符集,js字符串是由一组无符号的16位值组成的序列。最常用的Unicode字符都是通过16位的内码表示,并代表字符串中的单个字符,那些不能表示为16位的Unicode字符则遵循UTF-16编码规则——用两个16位值组成的一个序列(代理项对)表示。这意味着一个长度为2的js字符串有可能表示一个Unnicode字符。js定义的各式字符串操作方法均作用于16位值,而非字符,且不会对代理项做单独处理,同样js不会对字符串做标准化的加工,甚至不能保证字符串是合法的UTF-16格式。不过这些情况都在ES6中得到解决。