==、=== 与 Object.is() 的区别
在 JavaScript 中,==
(相等运算符)、===
(严格相等运算符)和 Object.is()
(对象相等判断)是三种不同的比较方式,它们在比较规则和适用场景上有明显差异。
一、==
(相等运算符)
1. 比较规则
- 类型相同:直接比较值,规则与
===
相同 - 类型不同:尝试类型转换后再比较,遵循以下规则:
- null 与 undefined:
null == undefined
为true
,且它们不与其他值相等 - 布尔值与其他类型:布尔值先转换为数字(
true
转为 1,false
转为 0) - 字符串与数字:字符串尝试转换为数字
- 对象与原始值:对象先调用
valueOf()
或toString()
转换为原始值
- null 与 undefined:
2. 示例
// 类型相同的情况
5 == 5; // true
'hello' == 'hello'; // true
true == true; // true
null == null; // true
undefined == undefined; // true
// 类型不同的情况
5 == '5'; // true(字符串 '5' 转换为数字 5)
true == 1; // true(布尔值 true 转换为数字 1)
false == 0; // true
null == undefined; // true
[] == 0; // true(数组转换为 '',再转换为 0)
'0' == false; // true(两者都转换为数字 0)
3. 潜在陷阱
[] == false; // true(数组转换为 '',再转换为 0,与 false 转换后的 0 相等)
'' == 0; // true(字符串 '' 转换为数字 0)
' ' == 0; // true(空白字符串转换为数字 0)
二、===
(严格相等运算符)
1. 比较规则
- 类型不同:直接返回
false
- 类型相同:比较值是否相等,但有两个特殊情况:
NaN
与任何值(包括自身)都不相等+0
与-0
被视为相等
2. 示例
// 类型相同且值相等
5 === 5; // true
'hello' === 'hello'; // true
true === true; // true
null === null; // true
undefined === undefined; // true
// 类型不同
5 === '5'; // false
true === 1; // false
null === undefined; // false
// 特殊情况
NaN === NaN; // false
+0 === -0; // true
三、Object.is()
(对象相等判断)
1. 比较规则
- 与
===
基本相同,但修正了两个特殊情况:NaN
与NaN
被视为相等+0
与-0
被视为不相等
2. 示例
Object.is(5, 5); // true
Object.is('hello', 'hello'); // true
Object.is(true, true); // true
Object.is(null, null); // true
Object.is(undefined, undefined); // true
Object.is(5, '5'); // false
Object.is(true, 1); // false
Object.is(null, undefined); // false
// 修正的特殊情况
Object.is(NaN, NaN); // true(与 === 不同)
Object.is(+0, -0); // false(与 === 不同)
四、三者对比表格
比较表达式 | == 结果 |
=== 结果 |
Object.is() 结果 |
||||
---|---|---|---|---|---|---|---|
5 == '5' |
true |
false |
false |
||||
true == 1 |
true |
false |
false |
null == undefined |
true |
false |
false |
[] == 0 |
true |
false |
false |
||||
'0' == false |
true |
false |
false |
||||
NaN == NaN |
false |
false |
true |
||||
+0 == -0 |
true |
true |
false |
||||
NaN === NaN |
false |
false |
true |
||||
+0 === -0 |
true |
true |
false |
||||
Object.is(NaN, NaN) |
true |
false |
true |
||||
Object.is(+0, -0) |
false |
true |
false |
五、使用建议
优先使用
===
- 避免类型转换带来的意外结果
- 代码更清晰,减少潜在错误
谨慎使用
==
- 仅在明确需要类型转换时使用(如判断
null
或undefined
) - 示例:
if (value == null)
等价于if (value === null || value === undefined)
- 仅在明确需要类型转换时使用(如判断
使用
Object.is()
的场景- 需要精确判断
NaN
或区分+0
和-0
- 例如:实现深度比较函数时
- 需要精确判断
六、面试高频问题
==
和===
的区别是什么?
答:==
在比较时会进行类型转换,而===
不会。===
只有在类型和值都相等时才返回true
。为什么
NaN === NaN
返回false
?如何判断一个值是否为NaN
?
答:这是 JavaScript 语言的设计。判断NaN
可以使用:Number.isNaN(value)
(ES6+,最可靠)Object.is(value, NaN)
- 全局
isNaN()
(但会将非数字值误判为NaN
)
Object.is()
解决了哪些问题?
答:Object.is()
解决了===
的两个特殊问题:Object.is(NaN, NaN)
返回true
Object.is(+0, -0)
返回false
以下表达式的结果是什么?为什么?
[] == 0; '0' == false; null == undefined;
答:
[] == 0
为true
:数组转换为字符串''
,再转换为数字0
'0' == false
为true
:两者都转换为数字0
null == undefined
为true
:这是==
的特殊规则
在什么情况下应该使用
==
?
答:仅在明确需要宽松比较时使用,例如:- 判断一个值是否为
null
或undefined
:if (value == null)
- 与预期可能为不同类型的值比较(如配置项可能是字符串或数字)
- 判断一个值是否为
总结
==
:宽松相等,允许类型转换,规则复杂,容易产生意外结果===
:严格相等,不允许类型转换,是最常用的比较方式Object.is()
:精确相等,修正了===
对NaN
和±0
的处理
在实际开发中,建议优先使用 ===
以提高代码的可靠性和可维护性。仅在明确需要类型转换时使用 ==
,并谨慎处理可能的陷阱。Object.is()
适用于需要精确比较的特殊场景。