JavaScript 类型转换面试题 10 例精讲:从 `Number([])` 到 `Boolean({})` 的陷阱
JavaScript 类型转换面试题 10 例精讲从Number([])到Boolean({})的陷阱1. 为什么Number([])返回 0 而Number([1])返回 1当数组转换为数字时JavaScript 会先调用valueOf()方法。如果返回的不是原始值再调用toString()方法[].toString() // 返回空字符串 [1].toString() // 返回 1空字符串转换为数字会得到 0而 1 转换为数字会得到 1。这就是为什么Number([]) // 0 Number([1]) // 1 Number([1,2]) // NaN (因为 1,2 无法转换为有效数字)2.Boolean({})和Boolean([])为何都返回 true在 JavaScript 中只有以下值会被转换为 falsefalse0(空字符串)nullundefinedNaN所有对象包括空对象和数组在布尔上下文中都会转换为 trueBoolean({}) // true Boolean([]) // true Boolean(new Boolean(false)) // 这也是 true3.5 - 2和5 2的结果为何不同减法运算符 (-) 会强制将操作数转换为数字5 - 2 // 3 (相当于 5 - 2)而加法运算符 () 在遇到字符串时会优先进行字符串连接5 2 // 52 (字符串连接) 5 2 // 52 (数字2被转换为字符串) 5 2 // 52 (数字5被转换为字符串)4. 为什么null undefined返回 true 而null undefined返回 false这是 JavaScript 的宽松相等 () 和严格相等 () 的区别null undefined // true (特殊规则) null undefined // false (类型不同)其他需要注意的情况null 0 // false undefined 0 // false NaN NaN // false (NaN不等于任何值包括它自己)5.[]为何返回 0 而{}返回 NaN一元加号运算符 () 会尝试将值转换为数字[] // 0 // 解析过程 // 1. [].valueOf() 返回数组本身(不是原始值) // 2. [].toString() 返回 // 3. Number() 返回 0 {} // NaN // 解析过程 // 1. {}.valueOf() 返回对象本身 // 2. {}.toString() 返回 [object Object] // 3. Number([object Object]) 返回 NaN6. 为什么!![]返回 true 而!!0返回 false双感叹号 (!!) 是将值转换为布尔值的常用技巧!![] // true (所有对象都为真) !!0 // false这与 Boolean 构造函数的结果一致Boolean([]) // true Boolean(0) // false7.b a a a会得到什么结果这个表达式展示了字符串连接和类型转换的复杂交互b a a a // baNaNa解析步骤a尝试将 a 转换为数字得到 NaN表达式变为b a NaN aNaN 被转换为字符串 NaN最终结果为 baNaNa8. 为什么[] ![]返回 true这个看似矛盾的结果揭示了 JavaScript 类型转换的复杂规则[] ![] // true解析过程![]首先将数组转换为布尔值 (所有对象为 true)然后取反得到 false比较变为[] false根据规则如果一边是对象另一边是布尔值先将布尔值转换为数字比较变为[] 0对象转换为原始值[].valueOf()返回数组本身 →[].toString()返回 比较变为 0空字符串转换为数字 0最终比较0 0返回 true9.parseInt(08)和Number(08)有何不同这两个函数处理前导零的方式不同parseInt(08) // 8 (ES5) Number(08) // 8但在 ES3 中parseInt(08)会返回 0因为它将字符串视为八进制。现代 JavaScript 引擎默认使用十进制解析除非明确指定基数parseInt(08, 10) // 8 (明确指定十进制) parseInt(08, 8) // 0 (八进制解析)10. 为什么{} []返回 0 而[] {}返回 [object Object]这个差异源于 JavaScript 解析器的行为{} [] // 0 ({}被解释为空代码块[]是转换为数字0) [] {} // [object Object] (正常进行字符串连接)在第一个例子中{}被解释为空的代码块而不是对象字面量所以实际执行的是[]结果为 0。而在第二个例子中[]转换为空字符串{}转换为[object Object]连接后得到[object Object]。快速自查清单对象到原始值转换先调用valueOf()如果不是原始值再调用toString()日期对象例外直接调用toString()宽松相等 () 的特殊规则null undefined为 true字符串和数字比较时字符串转换为数字布尔值和其他类型比较时布尔值先转换为数字转换为布尔值为 false 的值false0(空字符串)nullundefinedNaN加法运算符 () 的特殊行为如果任一操作数是字符串进行字符串连接否则将操作数转换为数字进行加法运算一元加号 () 和减号 (-) 运算符强制将值转换为数字new Date()获取时间戳的常用方法