Object.is() 与比较操作符 == 和 === 的区别是什么?

Object.is()是 JavaScript 中用于比较两个值是否完全相同的方法,它的比较规则与===(严格相等)非常相似,但在处理NaN+0/-0时有重要区别。

1.核心区别对比

比较场景==(宽松相等)===(严格相等)Object.is()
类型不同尝试转换后比较直接返回false直接返回false
NaN === NaNfalsefalsetrue
+0 === -0truetruefalse
普通值可能转换类型类型和值都相同类型和值都相同

2.详细区别说明

==(宽松相等)

  • 会进行类型转换后再比较
  • 规则复杂,容易出错
0=="0"// true(字符串转数字)null==undefined// true(特殊规则)false=="0"// true(都转为 0)[]==false// true(数组转数字为 0)

===(严格相等)

  • 不进行类型转换,类型不同直接返回false
  • 但有两个特殊行为:
    • NaN === NaN返回false
    • +0 === -0返回true
0==="0"// false(类型不同)null===undefined// false(类型不同)NaN===NaN// false(特殊规则)+0===-0// true(特殊规则)

Object.is()

  • ===基本相同,但修正了两个特殊值的行为:
    • Object.is(NaN, NaN)返回true
    • Object.is(+0, -0)返回false
Object.is(0,"0")// falseObject.is(null,undefined)// falseObject.is(NaN,NaN)// true(与 === 不同)Object.is(+0,-0)// false(与 === 不同)Object.is("hello","hello")// trueObject.is({a:1},{a:1})// false(对象引用不同)

3.为什么需要Object.is()

处理NaN的问题

在 JavaScript 中,NaN是唯一不等于自身的值:

NaN===NaN// false(不符合直觉)Object.is(NaN,NaN)// true(更合理)

区分+0-0

数学上+0-0相等,但在某些场景(如浮点运算)需要区分:

+0===-0// trueObject.is(+0,-0)// false

4.实际应用场景

使用Object.is()的场景

  • React 的useMemouseCallback依赖比较
  • Redux 的不可变数据比较
  • 需要精确判断两个值是否完全相同的场景
// React 示例constmemoizedValue=useMemo(()=>computeExpensiveValue(a,b),[a,b]);// React 内部使用 Object.is() 比较依赖项

何时使用哪个

  • 日常开发:优先使用===(更常见、性能更好)
  • 需要精确比较(特别是处理NaN+0/-0):使用Object.is()
  • 避免使用==(除非明确需要类型转换,如value == null检查nullundefined

5.实现原理

Object.is()的行为可以用以下逻辑模拟:

functionis(value1,value2){if(value1===value2){// 处理 +0 和 -0returnvalue1!==0||1/value1===1/value2;}// 处理 NaNreturnvalue1!==value1&&value2!==value2;}

总结

特性=====Object.is()
类型转换
NaN比较falsefalsetrue
+0vs-0truetruefalse
性能中等最快稍慢
推荐程度⚠️ 谨慎使用✅ 推荐✅ 特殊场景

最佳实践:默认使用===,在需要精确比较NaN或区分+0/-0时使用Object.is()