Object.assign 实现浅拷贝的核心是逐层复制可枚举属性值,只做一层赋值:基本类型值拷贝,引用类型地址拷贝;仅处理自身可枚举属性,跳过原型链、不可枚举属性及 null/undefined 源,不递归、不深拷贝、不处理特殊对象。

Object.assign 实现浅拷贝的底层机制,核心在于“逐层复制可枚举属性值”,而非递归遍历嵌套结构。它不关心值的类型,只做一层赋值操作:基本类型复制值,引用类型复制地址。
只遍历对象自身可枚举属性
Object.assign 不会处理原型链上的属性,只复制源对象 ownPropertyIsEnumerable === true 的键值对。比如通过 Object.defineProperty 设置为不可枚举的属性、或继承自原型的方法,都不会被拷贝。
- Symbol 类型的键也会被复制(只要它是可枚举的)
- null 或 undefined 作为源对象会被跳过,不报错
- 字符串、数组等类数组对象会被转为对象再取其可枚举索引属性
复制行为取决于值的类型,而非结构深度
它对每个属性值不做类型判断或递归处理,只是执行类似 target[key] = source[key] 的赋值:
- 遇到 number/string/boolean 等基本类型 → 值拷贝,彼此隔离
- 遇到 object/array/function/Date 等引用类型 → 地址拷贝,目标与源共享同一堆内存
- 如果源对象某属性是 getter,assign 会触发 getter 并把返回值赋给目标对象(不是复制 getter 本身)
目标对象始终被原地修改
Object.assign 返回的就是第一个参数(target),所有操作直接作用于该对象内存地址:
立即学习“Java免费学习笔记(深入)”;
- 若传入已有对象作 target,原对象会被更改
- 若想得到新对象,必须显式传入空对象
{}或Object.create(null) - 多个源对象按顺序合并,后出现的同名属性覆盖前面的
没有深拷贝逻辑,也不做防御性处理
它不检测循环引用,不处理 Map/Set/RegExp 等特殊内置对象,也不序列化函数或不可枚举字段:
- 遇到嵌套对象,仅复制外层引用,内部结构完全不动
- 若源对象中某个属性是 null 或 undefined,该 key 仍会被写入 target(值就是 null/undefined)
- 不能替代 JSON.parse(JSON.stringify()),因为后者会丢失函数、undefined、Symbol、循环引用等


















