私有字段(#field)内存开销与公有字段相近,因其直接嵌入实例对象、共享隐藏类结构;闭包则因每次创建独立Context并保守保留整个词法环境,导致堆内存峰值高15–25%、GC更频繁。

JavaScript 中私有字段(#field)在内存中并非“额外开销”,而是通过紧凑、结构化的方式直接嵌入实例对象,与公有字段共享相似的底层存储模型——关键差异不在访问权限,而在实现机制是否拖拽无关上下文。
私有字段直接存于实例对象内部
ES2022 引入的 #field 语法让私有状态真正绑定到对象实例本身。V8 引擎将其编译为 internal slot(内部槽位),和 this.field 一样位于对象的属性存储区,不依赖外层函数作用域。这意味着:
- 多个实例共享同一隐藏类(hidden class),内存布局高度一致;
- 每个
#value占用约 8 字节基础开销 + 值本身(如 number 占 8 字节); - Heap Snapshot 中显示为标准
Object,无额外Closure节点。
对比闭包模拟私有的内存代价
用工厂函数+闭包模拟私有字段时,引擎必须为每次调用创建独立的 Context 对象,它会保守保留整个词法环境(即使只用一个变量):
- 未使用的外层变量也可能被一并保留在内存中;
- 10 万个实例下,闭包版本堆内存峰值通常高出 15–25%,多出 3–4 MB;
- GC 更频繁且不可预测,尤其当闭包持有大对象(如缓存数组)时,易引发隐式强引用泄漏。
类型与对齐影响实际占用,而非 private 标签
内存大小由字段类型、数量、对齐规则决定,和修饰符无关:
立即学习“Java免费学习笔记(深入)”;
-
#count: number和count: number在 V8 中实例偏移量相同、字节宽度一致; - 若字段是对象引用(如
#cache: Map),开销来自Map实例本身,不是#符号; - 静态字段(
static #x)例外,它存在模块作用域或构造函数上,不随实例分配。
避免常见误判:不是“私有更省”,而是“实现更干净”
说私有字段“更省内存”不准确——真正优化的是结构可预测性与 GC 友好性:
- 类 +
#field让新生代对象更“干净”,Scavenge 次数减少; - 没有动态属性赋值或
delete操作时,隐藏类稳定,利于 JIT 编译优化; - 不要为了“私有”而用闭包,也不要因“public”就放弃封装——逻辑边界和内存边界是两回事。
文章来自机圈观察员网,发布者:,转载请注明出处:https://www.jqgcy.com/xinjizixun/87863.html