浅拷贝丢失属性描述符是因为其本质是“读取—赋值”过程,不复制元信息;Object.assign、展开运算符等仅获取getter返回值并写入普通属性,导致accessor、writable、enumerable、configurable等描述符全部失效。

浅拷贝不会传递属性描述符(如 get、set、writable、enumerable、configurable),它只读取并复制属性的当前值,丢失所有元信息。
为什么描述符在浅拷贝中丢失
Object.assign()、展开运算符({...obj})、for...in 循环等浅拷贝方式,本质是“读取—赋值”过程:它们调用属性的 getter(如果存在)拿到返回值,再以普通数据属性形式写入目标对象。原始的访问器定义、只读标记、不可枚举状态等描述符信息完全不参与该流程。
- getter/setter 被执行一次后变成静态值,新对象里只剩一个普通
value属性 -
writable: false的只读属性,在拷贝后默认变为可写(因赋值操作隐式设为writable: true) -
enumerable: false或configurable: false的属性会被忽略(如通过Object.defineProperty定义的不可枚举属性)
哪些属性会受影响
以下几类属性在浅拷贝中必然失效或行为异常:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 带
get/set的访问器属性(如obj.count是 getter,拷贝后变成固定数字) - Symbol 键名属性(
Object.assign和展开运算符不遍历 Symbol) - 不可枚举属性(
enumerable: false,例如Object.prototype.toString) - 原型链上的继承属性(浅拷贝只处理自有属性,不复制原型)
如何保留描述符完成真正拷贝
要完整复刻属性及其描述符,必须绕过“读取—赋值”路径,直接操作描述符本身:
立即学习“Java免费学习笔记(深入)”;
- 用
Object.getOwnPropertyDescriptors(obj)获取所有自有属性的完整描述符对象(含 Symbol 和不可枚举属性) - 用
Object.defineProperties(target, descriptors)将描述符批量重定义到新对象 - 若需保留原型链,先用
Object.create(Object.getPrototypeOf(obj))创建继承关系,再定义属性
实际效果对比示例
假设源对象有 getter 和私有状态:
const source = {
_x: 10,
get x() { return this._x * 2; },
set x(val) { this._x = Math.max(0, val); }
};-
const bad = {...source}→bad.x是数字20,无法再赋值 -
const good = Object.defineProperties({}, Object.getOwnPropertyDescriptors(source))→good.x仍具响应式读写能力

















