You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript对象属性如何在内存存储?新增属性是否会重分配内存?

JavaScript 对象属性存储机制解答

JS 引擎(以目前主流的 V8 为例)的对象存储逻辑和 C# 完全不同,你提到的「新增属性时迁移原对象内存位置」的情况不会发生。

核心存储结构

普通 JS 对象的底层分为三个独立的存储部分:

  • 对象本体:固定大小的堆内存块,创建后地址永久不变,只存两个指针:一个指向隐藏类(也叫 Shape/Map),另一个指向属性值存储数组。
  • 隐藏类:存储对象所有属性的元信息(比如属性名、属性值在存储数组里的偏移位置),作用是让属性查询不用每次遍历,能直接按偏移量快速取值,属于引擎的性能优化结构。
  • 属性值存储数组:所有属性的实际值都存在这个数组里,有初始预留容量。

对应示例的执行逻辑

你给出的两行代码执行流程如下:

let obj = {}; // Line 1
obj.prop1 = 1; // Line 2
  1. Line 1 执行时:引擎在堆中创建固定大小的空对象本体,同时生成对应空结构的隐藏类,以及带初始预留容量的空属性值存储数组,对象本体里存入两个结构的指针后,地址就固定不会再修改。
  2. Line 2 新增prop1属性时:
    • 引擎会基于原有隐藏类生成新的隐藏类,新增prop1对应的偏移量信息,把对象本体的隐藏类指针指向新的隐藏类。
    • 把数值 1 写入属性值存储数组的对应偏移位置即可。如果当前属性数量没有超出存储数组的预留容量,存储数组的位置也不会变;就算属性数量超了预留容量,引擎只会扩容迁移属性值存储数组,再把对象本体里的数组指针更新为新地址即可,对象本体的地址全程不变。

和 C# 逻辑的差异

C# 类的实例内存块会预分配所有预定义字段的存储空间,实例块本身大小是固定的,所以不支持动态加属性;C# 数组/List 扩容需要迁移整块内存,是因为它的内容直接存在连续的实例内存块里,逻辑和 JS 对象完全不同。


内容的提问来源于stack exchange,提问作者Jae Yi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 15:33:04