浅拷贝只复制对象第一层属性值,对基本类型(string、number、boolean、null、undefined、symbol)直接按值复制,互不影响;Object.assign()、扩展运算符等方法均逐个复制自有可枚举属性,不处理getter/setter、属性描述符及继承/不可枚举属性。

浅拷贝只复制对象第一层的属性值,对非对象属性(即基本类型:string、number、boolean、null、undefined、symbol)直接复制值本身,不涉及引用问题。
非对象属性的处理方式
基本类型在内存中存储的是实际值,浅拷贝时会把这份值完整复制一份,新旧对象互不影响。例如:
- 字符串、数字、布尔值:拷贝后修改新对象的该属性,原对象对应字段完全不变;
- null 和 undefined:直接赋值,无副作用;
- Symbol:ES6 起 Object.assign 和扩展运算符能正常拷贝 Symbol 键(前提是键可枚举),但不可枚举属性或原型链上的 Symbol 不会被复制。
常见方法对非对象属性的实际表现
所有主流浅拷贝手段——Object.assign()、{...obj}、Array.prototype.slice()、Array.prototype.concat()——在处理非对象属性时行为一致:
- 逐个读取源对象自有、可枚举的属性;
- 若属性值是基本类型,就按值复制到新对象;
- 不会触发 getter/setter(除非显式调用),也不会保留属性描述符(如 writable、enumerable);
- 继承属性(如 toString)、不可枚举属性(通过 Object.defineProperty 设置的 enumerable: false)均被跳过。
注意边界情况
看似“非对象”,但需警惕隐式包装对象和特殊值:
- new String() / new Number() 等包装实例属于对象类型,浅拷贝只复制引用,不是值;
- NaN、Infinity、-Infinity 在 JSON 深拷贝中会变成 null,但浅拷贝不受影响,正常复制为对应值;
- undefined 作为属性值 可被拷贝(Object.assign 会跳过 undefined 源参数,但作为属性值没问题);
- 函数 属于引用类型,浅拷贝复制的是函数引用,不是副本,修改函数本身极少发生,但两个对象共用同一函数实例。

















