鲁斯前端布鲁斯前端

文章中英模式

布鲁斯前端JS面试题目 - 严格比较、松散比较与 Object.is() 差异解析

深入解析 JavaScript 中的 ==、===、Object.is() 比较方式与实务应用,以及浅比较与深比较的差异。

影片縮圖

懒得看文章?那就来看视频吧

== vs ===

  • == 会进行类型转换,适合松散判断。
  • === 仅在类型和值都一致时才返回 true,为预设建议使用方式。
0 == '0'         // true
false == 0       // true
null == undefined // true
[] == false      // true

0 === '0'        // false
false === 0      // false
null === undefined // false

Object.is 精确比较

Object.is() 几乎等同 ===,但能正确处理 NaN+0/-0 等边界情况。

  • Object.is(NaN, NaN) // true
  • Object.is(+0, -0) // false
  • 适用于 React.memouseMemo、底层框架需精确判断变动时
Object.is(NaN, NaN);    // true
Object.is(+0, -0);      // false
Object.is(42, 42);      // true

const obj1 = { a: 1 };
const obj2 = { a: 1 };
Object.is(obj1, obj2);  // false(不同參考)

Object.is 是浅比较

Object.is() 只比较第一层 reference 或值,不会深入递归物件内容。

const a = { x: 1 };
const b = { x: 1 };

Object.is(a, b); // false
Object.is(a, a); // true

若需深比较,请使用如 lodash isEqual

import isEqual from 'lodash.isequal';
isEqual(a, b); // true

🔥 常见面试题目

(一) == === 差异为何?请举例。

解答:== 会进行类型转换,而 === 不会。

0 == ''            // true
false == 'false'   // false
'123' === 123      // false

(二) NaN === NaN 结果为何?

解答:NaN 在 IEEE 754 中被定义为不等于任何值(包含自己),所以 NaN === NaN false,但如果需要精准比较,可以使用 Object.is(NaN, NaN) ,结果会为 true

(三) Object.is 的使用时机?

解答:例如 React 内部为了判断 state 或 props 是否变化,使用 Object.is() 判断是否需要重新 render。这能避免 NaN+0/-0 等边界情况出错,确保精准性与效能。

useEffect(() => {
  // 一些代码...
}, [.....]) // <--- 依赖内部用Object.is比较

// 内部实现简单概览
// 如果新值与旧值透过 Object.is 比较为相同,就不更新
if (!Object.is(prevValue, nextValue)) {
  updateState(nextValue);
}