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


类型转换是 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 的比较规则特殊:

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

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

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

陷阱五:数组的特殊情况

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

陷阱六:多重类型转换

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

陷阱七: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  

欢迎补充。