es-toolkit/compat 的 eq 函数基于 SameValueZero 语义的相等性比较与 Object.is、 的全面对比【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit导读eq是 es-toolkit 为 Lodash 兼容层es-toolkit/compat提供的基础比较函数它使用 ECMAScript 规范中的SameValueZero语义判断两个值是否相等。本文围绕该函数的完整定义结合 eq 源码、eq 单元测试 与 compat 导出入口详细讲解其调用方式、与和Object.is()的差异边界以及在实际开发中应如何正确选择比较方式。eq 是什么SameValueZero 比较eq(value, other)用于检查两个值是否等价equivalent。它的核心特征是采用SameValueZero比较规则——这是 JavaScript 中比严格相等更“宽松”于NaN、比Object.is()更“宽松”于0/-0的一种语义。从源码看es-toolkit 的实现极为精简完整逻辑只有一行// 来源src/compat/util/eq.ts export function eq(value: any, other: any): boolean { return value other || (Number.isNaN(value) Number.isNaN(other)); }可以看到底层实现本质上是「严格相等 对NaN的特判」当两个值用比较不相等时再额外判断二者是否同时为NaN是则视为相等。这与测试用例 eq.spec.ts 中描述的行为完全一致。函数签名与参数const isEqual eq(value, other);参数类型说明valueany第一个待比较的值otherany第二个待比较的值返回值boolean两个值在 SameValueZero 语义下等价时返回true否则返回false。从测试用例还可以看出eq允许缺省参数eq()返回true两个undefined相等、eq(undefined)返回trueundefined与自身相等这与 Lodash 原版行为保持一致。基本用法与典型输出在项目中使用时需要从兼容入口导入import { eq } from es-toolkit/compat; // 基础用法 console.log(eq(1, 1)); // true console.log(eq(0, -0)); // trueSameValueZero 认为 0 与 -0 相等 console.log(eq(NaN, NaN)); // true console.log(eq(a, a)); // true console.log(eq(a, b)); // false参考测试 eq.spec.ts 可以归纳出更完整的判定矩阵返回true的情形eq()两个undefined、eq(undefined)、eq(0, -0)、eq(NaN, NaN)、eq(1, 1)以及同一对象引用的自身比较eq(object, object)返回false的情形eq(null, undefined)、eq(1, Object(1))原始值与装箱对象不等、eq(1, 1)不同类型不等、eq(object, { a: 1 })内容相同但引用不同的对象不等。其中最后一条值得特别强调eq只做“值 引用”层面的浅比较不做深度内容比较。两个结构完全相同的对象只要不是同一引用eq就返回false如果需要逐层比较对象内容应使用isEqual这类深比较函数而不是eq。eq 与 和 Object.is() 的行为差异eq之所以独立存在是因为它与 JavaScript 内置的两种比较方式都存在细微差别。原文档给出的对照示例非常直观// 使用 eq console.log(eq(NaN, NaN)); // true console.log(eq(0, -0)); // true // 使用 Object.is更快 console.log(Object.is(NaN, NaN)); // true console.log(Object.is(0, -0)); // falseObject.is 认为 0 与 -0 不同 // 使用 console.log(NaN NaN); // false console.log(0 -0); // true三种方式的差异可以归结为一个经典表格比较方式NaNvsNaN0vs-0avsa相同对象引用内容相同但引用不同的对象falsetruetruetruefalseObject.is()truefalsetruetruefalseeqSameValueZerotruetruetruetruefalse从源码实现可以精确解释这三者的关系严格相等NaN与自身不相等是eq唯一需要“打补丁”的缺口Object.is()把0与-0视为不同SameValue 语义而eq通过value other直接命中0 -0因此返回trueeq的结果在NaN之外全部复用再用Number.isNaN双端特判兜底NaN最终拼出 SameValueZero 完整语义。原文档提到Object.is是三者中性能较快的原生实现因此如果你的判定规则恰好是“NaN相等且0/-0不等”即 SameValue 语义直接使用原生Object.is()即可而需要与 Lodash_.eq行为完全对齐、追求兼容性时则应使用eq。在兼容层中的定位与导出方式eq位于兼容层的util目录下实现文件为 src/compat/util/eq.ts配套测试为 src/compat/util/eq.spec.ts。它通过 compat.ts 的统一入口对外导出// 来源src/compat/compat.ts第 279 行 export { eq } from ./util/eq.ts;因此在应用代码中可以直接写import { eq } from es-toolkit/compat;es-toolkit 同时提供普通入口es-toolkit与兼容入口es-toolkit/compateq作为 Lodash 兼容函数只从compat入口暴露这一点与文档标题中的 “Lodash Compatibility” 定位一致使用前需确认导入路径正确。典型应用场景与选型建议结合实现语义eq适合在以下场景中使用替代处理NaN判断例如判断某个计算结果是否为NaN或在缓存命中、去重逻辑中需要把NaN视为同一个值时保持与 Lodash 行为一致从 lodash 迁移到 es-toolkit 时_.eq可直接替换为eq而无需改动任何调用语义与isEqual分工需要深比较对象内容时用isEqual仅比较原始值或引用时用eq避免对简单场景付出深比较的开销。选型小结希望NaN与NaN相等、0与-0相等 → 选eq希望NaN相等但0与-0不等 → 选Object.is()需要深比较对象内容 → 选isEqual。总结eq是 es-toolkit 兼容层中最基础、最轻量的比较原语之一实现仅一行核心逻辑却精确复刻了 SameValueZero 语义补齐了对NaN的缺陷也保留了与Object.is()在0/-0上的差异。无论是从 lodash 迁移、在去重与缓存场景中统一NaN判定还是作为学习 JavaScript 比较语义的参考实现eq 源码 与 eq 测试 都是快速理解该函数行为边界的绝佳材料。【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
