外观
类型转换是按什么规则发生的?
显式转换是你调用 Number、String、Boolean。隐式转换发生在 +、==、if 和模板字符串里。面试先讲 ToPrimitive,再讲加号的特例。
原理
对象转原始值时先看 Symbol.toPrimitive,没有的话,数字场景优先 valueOf,字符串场景优先 toString。
+ 只要有一边是字符串,就变成字符串拼接;否则两边都转成数字。所以 1 + "2" 是 "12",1 + 2 是 3。
== 不转换类型的例外是 null == undefined。对象和原始值比较时,对象先转原始值。Boolean 会先变成数字再比。
假值只有:false、0、-0、0n、""、null、undefined、NaN。空数组是真值,但 [] == false 为真,因为两边都变成了 0。
追问
[] + {} 和 {} + [] 呢?
[] + {}:空数组变成空字符串,对象变成 "[object Object]",结果是 "[object Object]"。行首的 {} 可能被当成代码块,这是语法而不是加法,不要拿它当类型转换例子。
怎么避免意外转换?
比较用 ===。数字运算前用 Number 并检查 Number.isNaN。接口里的金额不要用二进制浮点硬算。
易错点
Boolean([])为真,[] == false也为真。两套规则不要混。Number("")是0,Number(" ")也是0,Number(null)是0,Number(undefined)是NaN。+"42"能转数字,+"42px"是NaN。解析带单位的字符串用parseFloat。