为什么 === 比 == 安全?7个类型转换黑洞

74 阅读1分钟

类型转换是 JavaScript 里最容易让人踩坑的特性之一。尤其是双等号(==)的隐式类型转换,经常会产生一些令人意想不到的结果。让我们一起深入了解这些陷阱,避免在实际开发中犯错。

陷阱一:数字与字符串比较

这可能是最常见的类型转换场景,但也藏着不少坑:

console.log(1 == '1') // true  
console.log(1 == '1.0') // true  
console.log(1 == '01') // true  
console.log(0 == '') // true  
  
// 更离谱的例子  
console.log(999 == '999fitness') // false  
console.log(0 == '0.0000') // true

这里的转换规则是:当数字和字符串比较时,会尝试将字符串转换为数字。但如果字符串不是一个有效的数字表示,结果就会出人意料。

陷阱二:布尔值的转换

布尔值在比较时会先被转换为数字(true 转为 1,false 转为 0):

console.log(true == 1) // true  
console.log(false == 0) // true  
console.log(true == '1') // true  
console.log(false == '') // true  
  
// 令人困惑的例子  
console.log(false == '0') // true  
console.log(true == '2') // false  
console.log(true == ['1']) // true 🤯

陷阱三:null 和 undefined

null 和 undefined 的比较规则特殊:

2ef6f6633fa63d82c07d02070f0947ed.png

这是因为 null == undefined 是特殊规定的,而在涉及大小比较时,null 会被转换为数字 0。

陷阱四:对象与原始类型比较

当对象与原始类型比较时,会调用对象的 valueOf() 或 toString() 方法:

06febd497a145f618dd1767b486ccad8.png

陷阱五:数组的特殊情况

空数组和数组的转换规则尤其令人困惑:

fe00218e117fd29e3ab9255daca76711.png

陷阱六:多重类型转换

当涉及多个操作数时,转换规则会变得更加复杂:

96250a8d1929848b633ec2c7ba9cd80b.png

陷阱七:NaN 的比较

NaN 是 JavaScript 中最特殊的值之一:

console.log(NaN == NaN) // false  
console.log(NaN === NaN) // false  
console.log(typeof NaN) // "number"  
  
// 正确的检查方式  
console.log(isNaN(NaN)) // true  
console.log(Number.isNaN(NaN)) // true