JS中相等比较

49,347 阅读2分钟

一、非严格比较‘==’

1.如果两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回true。

2.如果一个操作数是null,另一个操作数是undefined,则返回true。

3.如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型:

1.当数字与字符串进行比较时,会尝试将字符串转换为数字值。
2.如果操作数之一是Boolean,则将布尔操作数转换为1或0。
3.如果是true,则转换为1。如果是 false,则转换为0。 4.如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的valueOf()和toString()方法将对象转换为原始值。
5.如果操作数具有相同的类型,则将它们进行如下比较:

String:true仅当两个操作数具有相同顺序的相同字符时才返回。
Number:true仅当两个操作数具有相同的值时才返回。+0并被-0视为相同的值。如果任一操作数为NaN,则返回false。
Boolean:true仅当操作数为两个true或两个false时才返回true。

4.但是在特殊情况下,也就是两边都有对象的时候,会产生看似不合理的结果:

NaN == NaN; //false (参考第4条规则)
[] == []; //false
[] == ![]; //true
{} == {}; //false
{} == !{}; //false
在 JavaScript 中,Object、Array、Function、RegExp、Date 都是引用类型,声明引用类型的时候,变量名保存在js的栈内存里面,而对应的值保存在堆内存里面,而这个变量在栈内存中实际保存的是:这个值在堆内存中的地址,也就是指针。两个独立的 Object,它们的地址是不同的。
[] == ![] 和 {} == !{}
ECMAScript 中规定,逻辑非 (!) 的优先级高于相等操作符 ( == ),在比较 [] == ![] 的时候,先计算 ![] 得到布尔值 false,所以实际上比较的是 [] == false。

5.总结

如果相等操作符两边的操作数,不包含 null 或者 undefined,且两个操作数不全是对象(Object、Array、Function、RegExp、Date等), 在执行相等比较之前,会先调用 Number() 将两个操作数强制转为 Number 类型,然后进行比较。

二、严格等于(===)运算符之间最显着的区别在于,严格等于运算符不尝试类型转换。相反,严格相等运算符始终将不同类型的操作数视为不同。