Object.is:不止于“严格相等”的精确比较工具 说起 Ja vaScript 里的相等判断,===(严格相等)通常是我们的首选。但有没有一种情况,连 === 都觉得不够“严格”?答案是肯定的。这就引出了 Object.is 这个 ES6 引入的“裁判”。它和 === 很像,但在两个关键点上采取

说起 Ja vaScript 里的相等判断,===(严格相等)通常是我们的首选。但有没有一种情况,连 === 都觉得不够“严格”?答案是肯定的。这就引出了 Object.is 这个 ES6 引入的“裁判”。它和 === 很像,但在两个关键点上采取了更精确的立场:它能区分 +0 和 -0,并且判定 NaN 等于 NaN。这背后遵循的是 IEEE 754 浮点数标准的位模式比较逻辑,而非抽象相等算法。当然,它并不深入比较对象内容,因此在日常的相等判断中,=== 依然是更通用、更高效的选择。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
能,而且这是它与 === 最核心的差异之一。执行 Object.is(+0, -0) 会得到 false,而 +0 === -0 则返回 true。从数学角度看,零的符号不同确实有意义;Object.is 严格遵从 IEEE 754 规则,比较两者的位模式——+0 和 -0 的符号位相反,因此被判为不相等。
那么,什么时候该用上这个特性呢?
Object.is,=== 会掩盖这个差异。Object.is(x, -0),比传统的 1 / x === -Infinity 这种技巧更直观、更安全。Object.is(-0, 0) 同样返回 false,因为代码中的字面量 0 等价于 +0。另一个关键区别在于对 NaN 的处理。Object.is(NaN, NaN) 稳稳地返回 true,而 NaN === NaN 则永远是 false。原因在于,Object.is 不经过抽象相等算法,而是直接比较两个值的内部表示。在 IEEE 754 标准中,所有 NaN 都被视为“同一种不可比较的值”,Object.is 的规范则明确规定了它们彼此相等。
这带来了更精准的实践方案:
Math.sqrt(-1) 或 0 / 0 这类运算的结果时,使用 Object.is(result, NaN) 比 isNaN() 或 Number.isNaN() 更精准,后两者可能存在类型转换的干扰。result !== result 这种可读性差、且在特定调试或优化环境下可能不可靠的技巧来判断 NaN。Object.is 只对真正的 NaN 值生效,字符串 "NaN" 不会被误判。是不是所有情况都应该用更“严格”的 Object.is 呢?并非如此。在很多日常场景中,它的行为反而显得“过于严格”了。
使用前,不妨先看看这几个常见的注意点:
Object.is 和 === 一样,只比较引用是否相同,返回 false。别指望它能替代 _.isEqual 或 JSON.stringify 这类深度比较方案。=== 已经完全足够且语义清晰。引入 Object.is 反而可能让代码意图变得模糊。NaN 的特殊判断,Object.is 的性能通常略慢于 ===(在 V8 引擎中大约慢 10%~15%)。在超高频的循环中,这点差异值得权衡。=== 并手动补充对零符号和 NaN 的判断。直接使用 Object.is 有时会显得意图不够明确,也容易遗漏边界情况。一个不错的实践是根据具体需求,将其封装成语义更清晰的工具函数:
const isNegativeZero = (val) => Object.is(val, -0);
const isNaNValue = (val) => Object.is(val, NaN);
const isSameZero = (a, b) => {
if (!Object.is(a, b)) return false;
// 此时 a 和 b 已相等,但若都是 0,还需确认符号一致
return !Object.is(a, +0) || !Object.is(b, -0) || Object.is(a, b);
};
注意看最后一个 isSameZero 函数,它的逻辑看似有点绕,却恰恰揭示了一个关键点:Object.is 的真正价值,并不在于提供一个“更通用”的相等判断,而在于**让你能够精确控制对 +0/-0 和 NaN 的判定时机**。用错了场景,它不会让你的代码更简洁;但用对了地方,它能帮你堵住那些由浮点数特性引发的、极其隐蔽的逻辑漏洞。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述