标准答案

  1. 严格相等:=== 比较时通常要求类型和值都相同,不会为了比较而主动做类型转换。
  2. 宽松相等:== 如果两边类型不同,会按抽象相等规则先做隐式转换,再比较转换后的结果。常见规则包括 null == undefined 为 true、字符串和数字比较时字符串尝试转数字、布尔值先转数字、对象和原始值比较时对象会通过 ToPrimitive 转成原始值。
  3. 引用比较:对象和对象之间比较的是引用,不是结构内容,所以两个结构相同的对象用 == 或 === 通常也是 false。
  4. 工程取舍:业务代码默认使用 ===,因为它更可读、更可预测。少数例外是想同时判断 null 和 undefined 时,可以写 value == null。需要更精确地区分 NaN、+0、-0 时,可以用 Object.is。

题目解析

不需要把规范里的每一步都背出来,但要能说明隐式转换为什么危险:它把类型转换藏在比较表达式里,读代码的人很难第一眼判断结果。

=== 也不是“数学上的完全相等”。NaN !== NaN,+0 === -0。Object.is(NaN, NaN) 是 true,Object.is(+0, -0) 是 false。

代码示例

下面用几个小例子说明边界,再给出工程习惯。

JavaScript
null == undefined // true
null === undefined // false

'1' == 1 // true
'1' === 1 // false

NaN === NaN // false
Object.is(NaN, NaN) // true

if (value == null) {
  // 同时匹配 null 和 undefined
}

常见误区

  • 误以为 == 一定错误。它有规则,只是规则复杂,不适合日常业务默认使用。
  • 误以为 === 能处理 NaN。判断 NaN 应该用 Number.isNaN 或 Object.is。
  • 忽略对象比较的是引用,不是结构内容。

作者信息