标准答案
- 严格相等:=== 比较时通常要求类型和值都相同,不会为了比较而主动做类型转换。
- 宽松相等:== 如果两边类型不同,会按抽象相等规则先做隐式转换,再比较转换后的结果。常见规则包括 null == undefined 为 true、字符串和数字比较时字符串尝试转数字、布尔值先转数字、对象和原始值比较时对象会通过 ToPrimitive 转成原始值。
- 引用比较:对象和对象之间比较的是引用,不是结构内容,所以两个结构相同的对象用 == 或 === 通常也是 false。
- 工程取舍:业务代码默认使用 ===,因为它更可读、更可预测。少数例外是想同时判断 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。
- 忽略对象比较的是引用,不是结构内容。