Object.is() 与比较操作符 "==="、"==" 的区别

55 阅读3分钟

Object.is() 与比较操作符 "==="、"==" 的区别

1. 相等操作符 ==

== 是相等操作符,它会在比较时进行类型转换。

特点:

  • 比较前会进行类型转换
  • 如果两个操作数类型不同,则会尝试将它们转换为相同类型再比较
  • 对于对象,会先转换为原始值再比较

转换规则:

  • null == undefined 返回 true
  • 数字与字符串比较时,会将字符串转换为数字
  • 布尔值与其他类型比较时,会将布尔值转换为数字(true -> 1,false -> 0)
  • 对象与原始类型比较时,会调用对象的 valueOf()toString() 方法转换为原始值

例子:

1 == '1'           // true,字符串 '1' 被转换为数字 1
true == 1          // true,true 被转换为数字 1
null == undefined  // true,特殊规则
[] == ''           // true,[] 转换为 ''
[] == 0            // true,[] 转换为 '' 再转为 0
{} == '[object Object]' // true,{} 转换为字符串 '[object Object]'

2. 严格相等操作符 ===

=== 是严格相等操作符,它不会进行类型转换。

特点:

  • 不进行类型转换
  • 如果操作数类型不同,直接返回 false
  • 如果类型相同,比较值是否相同
  • 对于对象,只有引用同一个对象才返回 true

例子:

1 === '1'           // false,类型不同
true === 1          // false,类型不同
null === undefined  // false,类型不同
NaN === NaN         // false,NaN 不等于任何值,包括自身
+0 === -0           // true,视为相同值
{} === {}           // false,不同对象引用

3. Object.is()

Object.is() 是 ES6 新增的比较方法,它的比较方式与 === 类似,但有两个特殊情况处理不同。

特点:

  • 不进行类型转换
  • 大部分行为与 === 相同
  • 特殊处理 NaN+0/-0 的比较

=== 的区别:

  1. NaN 的比较:Object.is(NaN, NaN) 返回 true,而 NaN === NaN 返回 false
  2. +0-0 的比较:Object.is(+0, -0) 返回 false,而 +0 === -0 返回 true

例子:

Object.is(1, 1); // true
Object.is(1, "1"); // false,类型不同
Object.is(NaN, NaN); // true,特殊情况
Object.is(+0, -0); // false,特殊情况
Object.is({}, {}); // false,不同对象引用

4. 总结比较

比较内容=====Object.is()
类型转换
null == undefinedtruefalsefalse
1 == '1'truefalsefalse
NaN 与 NaNfalsefalsetrue
+0 与 -0truetruefalse
{} 与 {}falsefalsefalse

5. 手动实现 Object.is()

function myObjectIs(x, y) {
  // 处理 NaN 的情况
  if (x !== x && y !== y) {
    return true;
  }

  // 处理 +0 与 -0 的情况
  if (x === 0 && y === 0) {
    return 1 / x === 1 / y;
  }

  // 其他情况使用 === 比较
  return x === y;
}

// 测试
console.log(myObjectIs(1, 1)); // true
console.log(myObjectIs(NaN, NaN)); // true
console.log(myObjectIs(+0, -0)); // false
console.log(myObjectIs({}, {})); // false

6. 使用场景选择

  • 使用 ==:在明确需要类型转换的宽松场景下,如 if (x == null) 可同时检查 nullundefined
  • 使用 ===:大多数情况下的首选,避免隐式类型转换带来的问题
  • 使用 Object.is():当需要特别区分 +0-0,或特别处理 NaN 相等时

7. 性能考虑

通常情况下,性能从高到低的排序是:

  1. === (最快,因为是内置运算符且不需要类型转换)
  2. == (需要额外的类型转换逻辑)
  3. Object.is() (作为函数调用有额外开销)

在不需要特殊处理 NaN+0/-0 的场景下,优先使用 ===