类型转换是 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