javascript中类型转换的本质差异在于值与引用、可变性与不可变性:基本类型转换直接作用于值本身,引用类型必须先通过toprimitive降级为基本类型再转换。

基本类型和引用类型在 JavaScript 中的类型转换规则,本质差异在于“值 vs 引用”以及“可变性 vs 不可变性”。理解它们的转换行为,关键不是死记规则,而是抓住底层逻辑:基本类型转换只涉及值本身;引用类型转换则必须先降级为基本类型(通过 ToPrimitive),再按需转成字符串、数字或布尔值。
基本类型转其他基本类型:直接、确定、无副作用
基本类型之间的转换是显式且可预测的,不依赖对象方法,也不会改变原值:
-
转字符串:用
String(x)或x + ''。例如String(123)→"123",String(true)→"true",String(null)→"null",String(undefined)→"undefined" -
转数字:用
Number(x)、+x或算术运算(如x - 0)。Number("123")→123,Number("")→0,Number("abc")→NaN,Number(null)→0,Number(undefined)→NaN -
转布尔:用
Boolean(x)或!!x。只有false、0、""、null、undefined、NaN这六个假值转为false,其余一律为true
引用类型转基本类型:依赖 ToPrimitive,有优先级和隐式调用
引用类型不能直接变成另一个引用类型,所有转换都必须先降级为基本类型(字符串、数字或布尔),这个过程由引擎内部的 ToPrimitive 算法控制:
- 当需要字符串上下文(如
'' + obj、String(obj)),优先调用obj.toString();若返回基本值就用它,否则再调用obj.valueOf();若仍非基本值则报错 - 当需要数字上下文(如
obj - 1、Number(obj)),优先调用obj.valueOf();失败再试toString() - 所有对象转布尔值恒为
true(空数组[]、空对象{}、new Date(NaN)都不例外) - 常见例子:
[] == 0为true([] → "" → 0);[1] == 1为true([1] → "1" → 1);{}在数字上下文中转为NaN,所以{} == 0是false
== 运算符中的混合转换:基本类型优先,引用类型被迫降级
使用 == 比较不同类型的值时,JavaScript 会按固定规则尝试转换,目标是让两边都变成基本类型再比较:
- 如果一边是基本类型,另一边是引用类型(如
obj == 5),引擎自动对引用类型执行ToPrimitive,再与基本类型比较 -
null == undefined是唯一特例,直接返回true,不触发转换 -
0 == false为true(false → 0);"0" == false也为true(false → 0,"0" → 0) -
==不安全,容易产生意外结果;推荐统一使用===,避免隐式转换
赋值与函数传参中的“类型感知”行为
类型转换虽发生在表达式中,但赋值和传参方式暴露了根本差异:
- 基本类型赋值是值拷贝:
let a = "hi"; let b = a; b = "ho";→a仍是"hi" - 引用类型赋值是引用拷贝:
let x = {n: 1}; let y = x; y.n = 2;→x.n变为2 - 函数参数同理:传基本类型是副本,修改不影响外部;传对象是引用副本,修改属性会影响原对象(但重新赋值
obj = {}不影响外部变量)











