原始值直接存于调用栈中,不分配在堆上;全局声明随全局上下文创建/销毁,函数内声明随栈帧压入/弹出而生效/失效,块级作用域变量进入块时分配、离开时不可访问,生命周期由执行上下文自动管理,无手动释放或垃圾回收。

JavaScript 中原始类型数据的生存周期完全由执行上下文决定,不参与垃圾回收,也不需要手动管理。
原始值存在哪儿?
原始类型(number、string、boolean、null、undefined、symbol、bigint)不分配在堆上,而是直接存于调用栈中——比如函数调用时的栈帧,或全局/块级作用域对应的内存空间。长字符串底层可能复用堆上的字符数据,但变量本身只持有一个轻量描述符,语义上仍属栈管理。
- 全局声明:随全局执行上下文创建而分配,页面卸载时释放
- 函数内声明:函数调用时入栈,返回后栈帧自动弹出,变量即失效
- 块级作用域(let/const):进入块时分配,离开块时立即不可访问
它怎么“消失”?
原始值没有“释放”动作。所谓生命周期结束,只是栈指针移动、寄存器重用的自然结果。你不能也不该:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 用 delete 删除原始变量(语法错误或无效)
- 设为 null 或 undefined 来“腾内存”(仅改值,无实际意义)
- 尝试用 WeakRef 或 FinalizationRegistry 监听(它们只对堆对象有效)
装箱操作不影响原始值生命周期
写 "abc".length 或 42.toString() 会临时创建包装对象,但这个对象只在属性访问那一瞬间存在,操作完立刻销毁。原始值本身不受影响,也不会因此延长生命周期。
- "x".a = 1 不会留下任何痕迹,下一次 "x".a 仍是 undefined
- let s = "str"; s.custom = true 同样无效,因为赋值发生在瞬时包装对象上
- 这种机制是隐式的、只读的、不可引用的——和 new String("str") 有本质区别
和对象的根本区别
原始值不可变、按值传递、无引用关系;而对象在堆中分配,靠引用计数或标记清除被 GC 管理。哪怕一个数字字面量和一个 new Number(42) 值相等,它们的类型、内存位置、生命周期都完全不同。
- typeof 42 → "number",typeof new Number(42) → "object"
- 42 === new Number(42) → false
- 日常应避免显式使用包装构造函数
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










