JS 类型转换机制
1. 何时触发类型转换?
JS 是动态类型语言:声明时只有一种数据类型,直到运行期间才会确定当前类型。
let x = y ? 1 : a; // x 的值编译期无法获取
虽然变量的数据类型是不确定的,但各种运算符对数据类型有要求。如果运算子的类型与预期不符,就会触发类型转换机制。
2. 显示转换常见方法
Number():转为数字(含NaN)。parseInt(str, radix)/parseFloat(str):解析字符串到数字,遇到非数字字符停止。String():转为字符串。Boolean():转为布尔值。
3. Number 转换规则
Number('123'); // 123
Number('123abc');// NaN
Number(''); // 0
Number(true); // 1
Number(null); // 0
Number(undefined);// NaN
4. parseInt 转换规则
相比 Number 更宽松:逐字符解析,遇到不能转换的字符就停止。
parseInt('123abc'); // 123
parseInt('12.34'); // 12
parseInt('abc'); // NaN
parseInt('10', 2); // 2(二进制解析)
5. String 转换规则
- 普通值调用
toString()。 - 原始值(
null/undefined/boolean/number/symbol)有包装对象方法。 - 对象转换:先调用
Symbol.toPrimitive('string'),再toString(),再valueOf()。
6. Boolean 转换规则
Boolean(0); // false
Boolean(''); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
Boolean([]); // true
Boolean({}); // true
7. 何时发生隐式转换?
- 比较运算(
==、!=、<、>、<=、>=)。 - 算术运算(
+、-、*、/、%、++、--)。 - 一元运算符
+、-。
8. 隐式转换成 false 的值(Falsy)
undefinednull""(空字符串)NaN0、-0、+0document.all(历史遗留)
9. Symbol 值的强制类型转换
ES6 允许从符号到字符串的显式强制类型转换;隐式强制类型转换会产生错误。
- Symbol 不能被强制类型转换为数字(显式 / 隐式都报错)。
- Symbol 可以被强制类型转换为布尔值(结果都是
true)。
String(Symbol('a')); // 'Symbol(a)'
Symbol('a') + ''; // TypeError
Number(Symbol('a')); // TypeError
Boolean(Symbol('a')); // true
10. == 操作符的强制类型转换规则
- 字符串和数字比较:字符串转为数字后再比较。
- 其他类型和布尔比较:布尔先转为数字(
true→ 1,false→ 0)。 null == undefined为true;其他值和它们比较都返回false。- 对象和非对象比较:对象先调用
ToPrimitive(hint 为 default → number)后再比较。 - 任一操作数为
NaN→false(NaN !== NaN)。 - 两个对象比较:必须指向同一个对象才相等。
补充:ToPrimitive 抽象操作
将对象转换为原始值时,调用 ToPrimitive(input, preferredType?)。
preferredType 可以是 number 或 string,可省略。省略时:Date 当作 string,其他值当作 number。
当 preferredType = number 时:
- 如果 input 是原始值,直接返回。
- 否则调用
input.valueOf(),若结果是原始值则返回。 - 否则调用
input.toString(),若结果是原始值则返回。 - 否则报错。
当 preferredType = string 时,步骤 2 和 3 交换。
[] + []; // '' → 调用 ToPrimitive 得空字符串相加
[] + {}; // '[object Object]' → 双侧 toString
{} + []; // 0 → {} 被解析为代码块,+[] 转成 0
推荐:日常开发始终使用
===/!==,避免依赖隐式转换的细节。
来源整理自:我的有道云笔记



