游乐游手机版
首页/前端开发/文章详情

如何用Object.is()判定两个对象引用完全一致性的方法

时间:2026-06-18 06:56
Object is()是ES6引入的严格相等运算符,用于修正===无法区分+0与-0、以及NaN不等于自身的问题。但它仅比较引用地址,不深入比较对象内容。判断对象内容是否一致需采用其他方法,如JSON stringify浅层比较或使用Lodash等库进行深度比较。

在JavaScript的编程实践中,判断两个值的“相等”关系看似简单,实则隐藏着不少令人困惑的细节。开发者们熟知的严格相等运算符 === 虽然足够可靠,却存在两个广为人知的“小脾气”:它无法区分 +0-0,并且认为 NaN 不等于自身。为了解决这些边界场景,ES6 正式引入了 Object.is() 方法,专门修复了这两个反直觉的行为。

如何利用 Object.is() 判定两个对象引用的完全一致性

然而,这里有一个关键误区需要澄清:Object.is() 并不能用来判断两个对象的“内容”是否完全一致。 它的本质是 === 运算符的一个“增强补丁版”,其核心逻辑依然聚焦于严格比较引用地址。对于对象、数组这类引用类型,它不会递归地检查内部属性和结构。

Object.is() 的真实行为:精准但范围有限

简单来说,Object.is() 在绝大多数场景下与 === 的行为保持一致,仅修正了两个特例:

  • Object.is(+0, -0) 返回 false,而 === 会返回 true
  • Object.is(NaN, NaN) 返回 true,而 === 会返回 false
  • 对于对象、数组、函数等引用类型,Object.is(a, b) 只有在 ab 指向同一内存地址(即同一个引用)时才返回 true,这一结果与 a === b 完全一致。

为什么它无法胜任“对象内容一致”的判断?

根本原因在于它“不深入内部”进行递归比较。来看几个典型例子:

  • Object.is({a:1}, {a:1}) 返回 false。虽然内容相同,但两者是独立创建的对象,内存地址不同。
  • const a = {x: 1}; Object.is(a, a) 返回 true,因为这是同一个对象的同一引用。
  • Object.is([1,2], [1,2]) 同样返回 false。两个独立的数组,即使元素完全相同,地址也不同。

因此,如果你需要判断两个对象的结构和属性值是否完全一致,Object.is() 很快会让你失望。

若需判断对象“内容一致”,有何替代方案?

不必担心,针对不同场景和需求,JavaScript 社区已提供了多种成熟方案:

  • 快速浅层比较(仅第一层属性):可以使用 JSON.stringify(obj1) === JSON.stringify(obj2)。但需注意,该方法对属性顺序敏感,且会忽略函数、undefinedSymbol 类型的值,也无法处理循环引用的对象。
  • 可靠的浅比较:借助 Lodash 库的 _.isEqual()(它默认进行深比较,但可通过迭代次数控制),或者手动遍历对象自身属性,结合 Object.is()=== 逐个比较属性值。后者适用于结构已知的简单对象。
  • 深层全等比较(推荐):对于复杂嵌套对象,建议直接使用社区成熟工具库,例如 fast-deep-equallodash.isequal 或 Node.js 内置的 util.isDeepStrictEqual。它们已妥善处理了各种边界情况。
  • 自定义比较逻辑:在特定业务场景下,你可能需要明确比较哪些字段、忽略哪些字段,或特殊处理 DateRegExpMapSet 等类型。此时,编写一个自定义的比较函数是最灵活的选择。

小结:明确 Object.is() 的清晰定位

总而言之,Object.is() 的定位非常明确:它是一把为修复 ===NaN±0 上反直觉行为而设计的底层工具。它适用于需要精确原始值相等语义的场景,比如编写 Polyfill、处理算法中的边界条件。但它绝非用于对象内容比对的方案。若要判断两个对象是否“内容一致”,我们应当跳出引用比较的思维,转向值层面的深度分析。

来源:https://www.php.cn/faq/2471439.html
上一篇浏览器合成层如何规避位移动画显存暴涨 下一篇Bootstrap 5选项卡正确用法与迁移关键要点
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
如何在JavaScript中实现基于旋转视野的FOV射线绘制详解
前端开发 · 2026-07-01

如何在JavaScript中实现基于旋转视野的FOV射线绘制详解

如果用一句话概括核心,那就是:在 RayCasting 游戏开发中,绘制动态视野边界线(FOV)最可靠的方式是在逻辑层通过数学公式将坐标“算”出来,而不是依赖 Canvas 绘图上下文的旋转操作。 在实现类似 Doom 风格的 RayCasting 游戏时,动态视野(Field of View, F

TypeScript后端数据正确映射为前端接口类型的方法
前端开发 · 2026-07-01

TypeScript后端数据正确映射为前端接口类型的方法

在后端数据与前端类型之间来回转换,几乎是每位 TypeScript 开发者都无法回避的常态。后端返回的 car_brand、reg_number,和前端接口中定义的 brand、govtNumber,命名风格常常对不上号。此时,如果为了省事直接用 as 类型断言“强行”指认类型,那就踩进了常见的陷阱

动态HTML表格按层级条件合并单元格的JavaScript实现
前端开发 · 2026-07-01

动态HTML表格按层级条件合并单元格的JavaScript实现

本文详细讲解一种递归式 JavaScript 合并单元格方法,用于按列优先级(如前3列)智能合并表格行:仅当前一列已合并的前提下,才允许后续列合并相同值,从而精准实现多级分组与层级表格合并效果。 在动态生成的 HTML 表格中,按业务逻辑合并重复行是常见需求。然而,简单地对单列分别遍历合并——例如先

Next.js 13+重定向后滚动失效解决方案
前端开发 · 2026-07-01

Next.js 13+重定向后滚动失效解决方案

在 Next js App Router 的日常开发中,有一个令人颇为困扰的异常现象——当服务端执行 `redirect()` 跳转后,目标页面竟然无法正常滚动。没错,页面已经渲染完成,内容也完整显示,但垂直滚动条仿佛凭空消失。这个问题在 Next js 13 5 4 版本中尤为突出。 先给出结论:

WebGL图像加载延迟的纹理初始化时立即显示方法
前端开发 · 2026-07-01

WebGL图像加载延迟的纹理初始化时立即显示方法

本文详细介绍如何利用 Promise 与 async await 重构 WebGL 纹理加载流程,彻底解决首次渲染显示蓝色占位色、需要手动交互才能刷新的问题,实现文件导入后四张纹理平面即时正确渲染。 实际上,这个坑在 WebGL 开发中相当常见——纹理异步加载的小陷阱,说起来不大,但第一次遇到确实令