Object.is() 与比较操作符 "==="、"==" 的区别
1. 相等操作符 ==
== 是相等操作符,它会在比较时进行类型转换。
特点:
- 比较前会进行类型转换
- 如果两个操作数类型不同,则会尝试将它们转换为相同类型再比较
- 对于对象,会先转换为原始值再比较
转换规则:
null == undefined返回true- 数字与字符串比较时,会将字符串转换为数字
- 布尔值与其他类型比较时,会将布尔值转换为数字(
true-> 1,false-> 0) - 对象与原始类型比较时,会调用对象的
valueOf()或toString()方法转换为原始值
例子:
1 == '1' // true,字符串 '1' 被转换为数字 1
true == 1 // true,true 被转换为数字 1
null == undefined // true,特殊规则
[] == '' // true,[] 转换为 ''
[] == 0 // true,[] 转换为 '' 再转为 0
{} == '[object Object]' // true,{} 转换为字符串 '[object Object]'
2. 严格相等操作符 ===
=== 是严格相等操作符,它不会进行类型转换。
特点:
- 不进行类型转换
- 如果操作数类型不同,直接返回
false - 如果类型相同,比较值是否相同
- 对于对象,只有引用同一个对象才返回
true
例子:
1 === '1' // false,类型不同
true === 1 // false,类型不同
null === undefined // false,类型不同
NaN === NaN // false,NaN 不等于任何值,包括自身
+0 === -0 // true,视为相同值
{} === {} // false,不同对象引用
3. Object.is()
Object.is() 是 ES6 新增的比较方法,它的比较方式与 === 类似,但有两个特殊情况处理不同。
特点:
- 不进行类型转换
- 大部分行为与
===相同 - 特殊处理
NaN和+0/-0的比较
与 === 的区别:
NaN的比较:Object.is(NaN, NaN)返回true,而NaN === NaN返回false+0和-0的比较:Object.is(+0, -0)返回false,而+0 === -0返回true
例子:
Object.is(1, 1); // true
Object.is(1, "1"); // false,类型不同
Object.is(NaN, NaN); // true,特殊情况
Object.is(+0, -0); // false,特殊情况
Object.is({}, {}); // false,不同对象引用
4. 总结比较
| 比较内容 | == | === | Object.is() |
|---|---|---|---|
| 类型转换 | 是 | 否 | 否 |
| null == undefined | true | false | false |
| 1 == '1' | true | false | false |
| NaN 与 NaN | false | false | true |
| +0 与 -0 | true | true | false |
| {} 与 {} | false | false | false |
5. 手动实现 Object.is()
function myObjectIs(x, y) {
// 处理 NaN 的情况
if (x !== x && y !== y) {
return true;
}
// 处理 +0 与 -0 的情况
if (x === 0 && y === 0) {
return 1 / x === 1 / y;
}
// 其他情况使用 === 比较
return x === y;
}
// 测试
console.log(myObjectIs(1, 1)); // true
console.log(myObjectIs(NaN, NaN)); // true
console.log(myObjectIs(+0, -0)); // false
console.log(myObjectIs({}, {})); // false
6. 使用场景选择
- 使用
==:在明确需要类型转换的宽松场景下,如if (x == null)可同时检查null和undefined - 使用
===:大多数情况下的首选,避免隐式类型转换带来的问题 - 使用
Object.is():当需要特别区分+0和-0,或特别处理NaN相等时
7. 性能考虑
通常情况下,性能从高到低的排序是:
===(最快,因为是内置运算符且不需要类型转换)==(需要额外的类型转换逻辑)Object.is()(作为函数调用有额外开销)
在不需要特殊处理 NaN 或 +0/-0 的场景下,优先使用 ===。