【JavaScript】 隐式类型转换

发布时间:2026/6/26 8:22:06
【JavaScript】 隐式类型转换 JavaScript 是弱类型语言在运算过程中会自动进行类型转换这就是隐式类型转换Implicit Coercion。一、类型转换的三大核心规则JavaScript 的隐式转换主要围绕三种类型进行字符串String、数字Number、布尔值Boolean。1. 转换为字符串ToString原始值转换结果undefined‘undefined’null‘null’true‘true’false‘false’0‘0’NaN‘NaN’对象调用 toString() 或 valueOf()2. 转换为数字ToNumber原始值转换结果undefinedNaNnull0true1false0‘’空字符串0‘123’数字字符串123‘abc’非数字字符串NaN对象调用 valueOf() 或 toString()3. 转换为布尔值ToBoolean假值Falsy转换为 falseundefinednullfalse0、-0、0nNaN‘’空字符串其他所有值都是真值Truthy包括’ 空格字符串‘false’字符串[]空数组{}空对象二、常见触发隐式转换的场景1. 算术运算符、-、*、/、%运算符特殊任一操作数是字符串 → 字符串拼接否则 → 数字加法// 字符串拼接12// 12hello1// hello1trueabc// trueabc// 数字加法1true// 2true → 11null// 1null → 01undefined// NaNundefined → NaN1[]// 1[] → 然后拼接1{}// 1[object Object]其他算术运算符-、*、/、%强制转为数字不进行字符串拼接5-3// 25*2// 1010/2// 510%3// 1abc-1// NaN5-null// 5null → 05-undefined// NaN2. 比较运算符宽松相等类型相同 → 直接比较类型不同 → 转为数字再比较11// true1 → 1true1// truetrue → 1false0// truefalse → 0nullundefined// true特殊规则null0// falsenull 只与 undefined 相等NaNNaN// falseNaN 不等于任何值1true// true都转数字1 1abctrue// falseabc → NaNNaN ! 1[]// true[] → []0// true[] → → 0[1]1// true[1] → 1 → 1[1,2]1,2// true数组转字符串{}[object Object]// true严格相等不进行类型转换类型不同直接返回 false11// falsetrue1// falsenullundefined// false关系比较、、、两个操作数都是字符串 → 字典序比较否则 → 转为数字比较210// true字符串比较2 10210// false10 → 10210// false2 → 2abc1// falseabc → NaN任何比较都是 falsenull0// falsenull → 0null0// truenull → 03. 逻辑运算符!逻辑非转为布尔值后取反!0// true0 → false → true!1// false!// true!hello// false!null// true!undefined// true![]// false[] 是 truthy!{}// false{} 是 truthy和||返回操作数本身不是布尔值// 如果第一个是 falsy返回第一个否则返回第二个0hello// 01hello// hellonull5// null// ||如果第一个是 truthy返回第一个否则返回第二个0||hello// hello1||hello// 1null||5// 54. 条件语句if、while、for、三元运算符条件表达式会转为布尔值if(0){}// false不执行if(){}// false不执行if(null){}// false不执行if([]){}// true执行[] 是 truthyif({}){}// true执行{} 是 truthyconstresult0?yes:no// no5. 一元运算符// 0123// 123abc// NaNtrue// 1false// 0null// 0undefined// NaN[]// 0[] → → 0{}// NaN{} → [object Object] → NaN-// -0-123// -123-abc// NaN三、对象/数组的转换ToPrimitive当对象包括数组、函数等参与运算时会先执行ToPrimitive操作将其转换为原始值。转换流程:优先调用 Symbol.toPrimitive如果存在否则根据上下文提示hint调用 valueOf() 或 toString()constobj{valueOf(){return10;},toString(){returnhello;}};console.log(obj5)// 15使用 valueOfconsole.log(String(obj))// hello使用 toStringhint 是 stringconsole.log(obj)// 10使用 valueOfhint 是 number数组的特殊行为:[][]// 两个数组都转空字符串[]{}// [object Object]{}[]// 0在浏览器中{} 被解析为代码块相当于 [][1,2][3,4]// 1,23,4数组转字符串1,2 3,4[1]1// 11[1] → 1 → 1 1[1]-1// 0[1] → 1 → 1 - 1自定义 ToPrimitiveconstobj{[Symbol.toPrimitive](hint){if(hintnumber)return10;if(hintstring)returnhello;returnnull;}};console.log(obj5)// 15number hintconsole.log(${obj})// hellostring hintconsole.log(obj)// nulldefault hint四、特殊陷阱和难点运算符的歧义// 一元 和二元 不同[]// 0一元 转数字[][]// 二元 字符串拼接// 注意区分123// 33从左到右3 3 → 33123// 123从左到右12 3 → 123null和undefined的特殊性nullundefined// true特殊规则nullundefined// falsenull0// falsenull 只与 undefined 相等undefined0// falseNumber(null)// 0Number(undefined)// NaN数组比较的陷阱[]![]// true![] → !Boolean([]) → !true → false→0数组转原始值[] → → Number() → 000[][]// false引用比较不是同一个对象[1][1]// false引用比较[1]1// true[1] → 1 → 1布尔值比较的陷阱if( ){}// true空格字符串是 truthyif(false){}// true字符串 false 是 truthyif(0){}// falseif(newBoolean(false)){}// true对象总是 truthySymbol 的特殊性constsymSymbol(id);sym1// TypeError不能隐式转换 SymbolString(sym)// Symbol(id)可以显式转换五、如何避免隐式转换的坑使用严格相等和!// 避免if(value0){}// 推荐if(value0){}if(valuenull||valueundefined){}2.显式类型转换 javascript// 不推荐5-0// 5// 推荐Number(5)// 5parseInt(5,10)// 55// 5一元 是显式转数字// 不推荐5// 5// 推荐String(5)// 5${5}// 5使用Number.isNaN()检测 NaNisNaN(abc)// true先转数字Number.isNaN(abc)// false不转换直接判断Number.isNaN(NaN)// true使用Object.is()替代 NaNNaN// falseNaNNaN// falseObject.is(NaN,NaN)// true0-0// trueObject.is(0,-0)// false六、常见面试题汇总console.log([]![])// true ![] → !Boolean([]) → !true → false→0数组转原始值[] → → Number() → 000console.log([]0)// trueconsole.log([])// trueconsole.log({}0)// false{} → [object Object] → NaNconsole.log({}[object Object])// trueconsole.log(5-3)// 2console.log(53)// 53console.log(5-3)// 2console.log(53)// 53console.log(truefalse)// 1console.log(truetrue)// 2console.log([][])// console.log([]{})// [object Object]console.log({}[])// 0浏览器或 [object Object]// 4. 输出什么console.log(123)// true1 2 → true → 1 3 → trueconsole.log(321)// false3 2 → true → 1 1 → false// 5. 输出什么consta{valueOf(){return1;},toString(){return2;}};console.log(a1)// 2valueOf 优先console.log(String(a))// 2toString 优先

月新闻