JavaScript原始类型(number、string等)直接存储在栈中,按值访问、不可变、无引用关系;赋值时拷贝值本身,修改变量仅覆盖原值,不共享内存。

JavaScript中原始数据类型(如number、string、boolean、null、undefined、symbol、bigint)**不存储在堆中,而是直接存放在栈内存里**,且按值访问、不可变、无引用关系。
原始类型全部驻留在栈内存
当声明一个原始类型的变量时,比如:
let a = 42; let b = "hello"; let c = true;
这些值(42、"hello"、true)会**直接写入当前执行上下文的栈帧中**。栈空间由引擎自动管理,分配快、回收快,生命周期与作用域绑定。
- 每次赋值都是拷贝值本身,不是地址
- 修改变量只是用新值覆盖旧值,原位置被替换
- 不存在“多个变量指向同一块原始值内存”的情况
栈中存储的是实际值,不是指针
这和对象类型有本质区别:对象变量在栈中存的是指向堆内存的引用(指针),而原始类型变量在栈中存的就是值本身。
立即学习“Java免费学习笔记(深入)”;
例如:
let x = 100; let y = x; x = 200;
执行后y仍是100——因为y拿到的是x当时值的副本,两者完全独立。栈中为x和y各自分配了存放数字的空间。
小字符串和短数字也走栈,不因长度触发堆分配
即使字符串很长(如 1000 个字符),只要它是字面量或通过基本包装类型生成的原始值,依然作为整体存于栈中(V8等引擎可能做内部优化,比如将长字符串的底层字符数据放堆,但对JS开发者而言,该字符串仍表现为栈语义:不可变、按值传递、无引用共享)。
-
const s1 = "a".repeat(10000);→ 行为上仍是原始值:赋值、传参都拷贝内容逻辑 - 没有
s1 === s2为true却s1[0] = 'b'能改原值的情况(原始值禁止属性赋值) -
Object.is(s1, s2)比较的是值相等,不是内存地址相同
原始值的“不可变性”源于语言规范,不是内存布局强制结果
虽然原始值存在栈中,但JS规定它们是不可变的(immutable)。比如:
let str = "abc"; str[0] = "x"; // 静默失败,str仍是"abc"
这不是因为栈不允许修改,而是引擎在访问str[0]时返回一个新字符串的临时包装对象,且赋值操作被忽略。所有原始类型的修改操作(如str.toUpperCase())都返回新值,原值不动。
- 不可变性是语义约束,保障按值行为的一致性
- 它让函数式编程模式(如纯函数、无副作用)天然可行
- 和内存位置无关——即使未来引擎把某些原始值放堆,只要保持不可变+按值语义,对代码无影响


















