实现Object.is

手写实现ES6中的Object.is方法,用于判断两个值是否严格相等

问题

Object.is() 是 ES6 新增的方法,用于判断两个值是否严格相等。它与 === 运算符类似,但在两个特殊情况下表现不同:

  1. +0-0 被认为是不相等的
  2. NaNNaN 被认为是相等的

需要实现一个 myObjectIs 函数,模拟 Object.is() 的行为。

解答

function myObjectIs(x, y) {
  // 如果两个值完全相同
  if (x === y) {
    // 需要排除 +0 和 -0 的情况
    // 1 / +0 = Infinity
    // 1 / -0 = -Infinity
    return x !== 0 || 1 / x === 1 / y;
  }
  
  // 如果两个值都是 NaN
  // NaN 是唯一一个不等于自身的值
  return x !== x && y !== y;
}

使用示例

// 普通值比较
console.log(myObjectIs(1, 1));           // true
console.log(myObjectIs('hello', 'hello')); // true
console.log(myObjectIs(true, true));     // true
console.log(myObjectIs(null, null));     // true
console.log(myObjectIs(undefined, undefined)); // true

// 不同值比较
console.log(myObjectIs(1, 2));           // false
console.log(myObjectIs('hello', 'world')); // false
console.log(myObjectIs(true, false));    // false

// 特殊情况1:+0 和 -0
console.log(myObjectIs(+0, -0));         // false
console.log(+0 === -0);                  // true (===运算符认为相等)

// 特殊情况2:NaN
console.log(myObjectIs(NaN, NaN));       // true
console.log(NaN === NaN);                // false (===运算符认为不相等)

// 对象比较(比较引用)
const obj = { a: 1 };
console.log(myObjectIs(obj, obj));       // true
console.log(myObjectIs({ a: 1 }, { a: 1 })); // false

// 与原生 Object.is 对比
console.log(myObjectIs(+0, -0) === Object.is(+0, -0));     // true
console.log(myObjectIs(NaN, NaN) === Object.is(NaN, NaN)); // true

关键点

  • 处理 +0 和 -0:当 x === y 时,需要额外判断是否为 0,如果是 0,通过 1/x === 1/y 来区分 +0 和 -0(因为 1/+0 = Infinity1/-0 = -Infinity

  • 处理 NaN:利用 NaN 的特性(NaN 是唯一不等于自身的值),通过 x !== x && y !== y 来判断两个值是否都是 NaN

  • 其他情况:对于其他所有情况,直接使用 === 运算符的结果即可

  • 逻辑

    • 先用 === 判断,如果相等则排除 ±0 的特殊情况
    • 如果不相等,则检查是否都是 NaN
    • 这样就覆盖了所有情况