JavaScript原始类型(number、string、boolean、null、undefined、symbol、bigint)的值直接存于栈内存中,按值访问、不可变、独占内存、生命周期由执行上下文自动管理,不依赖垃圾回收。

JavaScript 中原始类型(number、string、boolean、null、undefined、symbol、bigint)的值,直接存放在栈内存中——不是地址,不是引用,就是那个值本身。
栈里存的是值,不是指针
当你写 let a = 42,V8 引擎会在当前函数的栈帧中分配一块固定大小的空间,把 42 这个数字原样写进去。后续读取 a,引擎直接从那个位置取数;赋值 a = 99,就是用新值覆盖旧值。整个过程不涉及堆,也不生成任何地址跳转。
- 字符串哪怕长达上万字符,逻辑上仍是“按值存储”:赋值、传参、比较都基于内容本身
-
str[0] = 'x'静默失败,不是因为栈限制,而是语言规范强制原始值不可变 - 每个原始变量独占一份内存,
let b = a是复制数值,不是共享地址
生命周期由执行上下文自动管理
栈内存和函数调用强绑定。函数开始执行,它的局部原始变量被压入栈;函数返回,整块栈帧立即弹出,所有变量瞬间释放——不需要垃圾回收器介入。
- 不会意外滞留,也不会因闭包而“逃逸”,除非被长期捕获(此时 V8 会主动将其提升至堆,但对外仍表现为值语义)
-
const只锁定变量绑定,防止重新赋值,不改变存储位置或内存行为 - 递归过深或局部变量过多可能触发栈溢出(Chrome 约 1–2 MB 栈空间)
为什么原始类型必须在栈里
原始类型体积小、长度固定(如 number 总是 64 位浮点)、使用高频——放栈里能实现极快读写,且天然契合函数调用流程。
立即学习“Java免费学习笔记(深入)”;
- 堆适合生命周期不确定、结构复杂、体积可能很大的对象
- 若把对象硬塞进栈,每次函数调用/返回都要复制大量数据,栈易溢出,上下文切换成本剧增
- 原始类型存栈、对象存堆,是性能与灵活性之间的关键平衡
你写的每行 let x = ,只要右边是原始值,它就实实在在躺在栈里,等着被快速读、被干净释放。


















