简单来说, “= =” 是先转换类型再比较,“===”会先判断类型再比较,如果不为同一类型直接为false
“===”表示恒等,两边要绝对相同才为true
如图所示:同样的两边比较,双等与绝等会得到不同的结果
先说 ===的具体比较规则,如下:
- 如果类型不同,则不相等
- 如果类型相同,则进行值比较,如果值不相同也就不相等,如果值相同则相等
- 例外的是,NaN互相比较或者有一个为NaN,则都是不相等,判断NaN用isNaN()这个函数进行判断
==的具体比较规则,如下:
- 如果两个值类型相同,进行 === 比较,比较规则同上
- 如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较:
1.如果一个是null、一个是undefined,那么相等。
2.如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。
3.如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0再比较。
4.如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。
这里不难发现,复合类型的数据(比如对象、数组、函数等)之间的比较不是比较他们的值是否相等,而是比较他们引用的对象是否一样。
接下来我们看一道比较典型的基础面试题
两个空数组的比较,不管是双等还是恒等都是为false
首先我们要知道
基本数据类型的比较是值的比较:
- 值相等时就相等(==)
- 值和类型都相等时就恒等(===)
但引用类型和基本数据类型不同,引用类型的比较并非值的比较,而是引用的比较:
- 即使两个对象包含同样的属性及相同的值,它们也是不相等的
- 即使两个数组各个索引元素完全相等,它们也是不相等的
例子:
我们通常将对象称为引用类型(reference type),以此来和JavaScript的基本类型区分开来。对象值都是引用(reference),对象的比较均是引用的比较:当且仅当它们引用同一个基对象时,它们才相等。
例子:
所以回到题目,两个空数组相当于就是去new两个空的数组,它们有各自的内存空间。而比较规则是比较引用
如果这两个数组都相等了,那改变其中一个数组的值,另外一个也会跟着变的。这样程序变量就乱了。