object.assign执行单层浅拷贝时不产生额外物理内存开销,仅复制属性键值对;内存变化取决于目标对象是否存在、是否扩容及属性值类型:空目标触发初始内存分配,非空且容量足够时原地复用,扩容时触发重哈希;相比扩展运算符,它可复用目标对象,省去新对象头和槽位分配开销。

Object.assign 在执行单层浅拷贝时,本身不产生额外的“物理内存开销”——它只是将源对象的可枚举属性(键值对)逐个赋值到目标对象上,不创建新对象,也不复制嵌套结构。真正的内存变化取决于目标对象是否已存在、是否扩容,以及属性值的类型。
目标对象是空对象时:分配新内存块
当 target 是一个全新空对象(如 {}),Object.assign 会触发 JavaScript 引擎为该对象分配初始内存空间,用于存储其自有属性。这个过程涉及:
- 为对象头(object header)预留空间(含类型标记、GC 元信息等)
- 为属性槽(property slots)预分配哈希表或线性结构(V8 中常用“隐藏类 + 属性字典”动态切换)
- 每个字符串键和原始值(number/string/boolean)直接存入,开销小
- 若属性值是引用类型(如数组、对象、函数),只复制指针(8 字节典型大小),不复制其所指向的堆内存
目标对象非空且容量足够:原地复用,几乎零新增开销
如果 target 已存在,且已有足够属性槽容纳新属性,Object.assign 仅做字段覆盖或追加,不触发内存重分配。例如:
const target = { a: 1, b: 2 };<br>Object.assign(target, { c: 3, d: 4 }); // 仅写入 c/d,无新内存分配
此时内存增长仅来自两个新属性的键(字符串)和值(数字)本身,与手动 target.c = 3 等价。
目标对象需扩容时:触发隐式重哈希或数组式扩展
当 target 的属性数量超过当前容量阈值(V8 中默认约 10–16 个属性),引擎会重新分配更大的属性存储结构(如从 Fast Properties 切换到 Dictionary Mode),并迁移已有键值对。这会产生临时内存峰值和 CPU 开销,但属于一次性行为,不是 Object.assign 特有,而是对象动态增长的通用机制。
对比扩展运算符:关键差异在对象创建环节
扩展运算符 {...src} 总是新建对象,必然触发完整内存分配;而 Object.assign 可复用已有 target,避免了对象头和初始槽位的重复申请。因此在合并大对象且允许修改原 target 的场景下,Object.assign 的内存效率更高——它省掉的是“新对象壳”的开销,而非深层数据复制的开销。











