什么是SameValueZero 算法

21 阅读2分钟

SameValueZero 是 JavaScript 中的一种相等性比较算法,主要用于某些内置操作(如 Array.includes()Set 和 Map),与严格相等运算符 === 类似,但在处理 NaN 和 正负零时有特殊规则。

算法规则

基本比较流程

  1. 类型检查:如果两个值类型不同,直接返回 false
  2. 非数值类型:按 === 规则比较(类型相同且值相同则为 true)
  3. 数值类型:特殊处理以下情况:

数值类型特殊规则(Number 类型)

情况SameValueZero 返回值
x 和 y 都是 NaNtrue
x 是  +0 且 y 是 -0true
x 是 -0 且 y 是  +0true
x 和 y 数值相等(非 NaN、非零)true
其他情况false

注:这与 === 的唯一区别是:=== 认为 NaN 不等于自身,且 +0 等于 -0;而 SameValueZero 认为 NaN 等于自身,且同样认为 +0 等于 -0(与 === 在零的处理上一致)。

与其他相等算法的对比

比较算法实现方式+0 == -0NaN == NaN使用场景
SameValueZero内置算法(无直接 API)truetrueArray.includes()SetMap 等
=== (严格相等)JavaScript 运算符truefalse大多数需要类型严格比较的场景
Object.is()JavaScript 方法falsetrue需要精确区分 +0 和 -0 的场景
== (宽松相等)JavaScript 运算符truefalse类型自动转换的宽松比较

实现方式

虽然 SameValueZero 没有直接作为 JavaScript API 公开,但可以自定义实现:

function sameValueZero(x, y) {
  if (typeof x === "number" && typeof y === "number") {
    // 处理 NaN 和正负零
    return x === y || (x !== x && y !== y); // x !== x 检测 NaN
  }
  // 其他类型按 === 比较
  return x === y;
}

应用场景

SameValueZero 算法主要用于以下内置操作:

  1. Array.prototype.includes(searchElement) :判断数组是否包含特定元素时使用
const arr = [0, NaN];
arr.includes(-0); // true
arr.includes(NaN); // true
  1. Set 数据结构:在添加和查询元素时用于去重和相等性检查
const set = new Set([0, NaN]);
set.has(-0); // true
set.has(NaN); // true
  1. Map 数据结构:用于键的相等性比较

为什么选择 SameValueZero?

在搜索和集合操作中,SameValueZero 提供了更符合直觉的行为:

  • NaN 被视为自等:在数据搜索中,我们通常希望所有 NaN 值被视为相同(例如,查找数组中的无效数字)
  • 不区分正负零:在大多数应用场景中,0 和 -0 的差异并不重要,将它们视为相等更合理

总结

SameValueZero 是 JavaScript 中一种特殊的相等性比较算法,它与 === 基本相同,但在处理 NaN 和 正负零时有特殊规则。它主要用于 Array.includes()SetMap 等内置操作,为这些数据结构提供了更符合直觉的相等性判断。