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

JS对象解构丢失getter定义,如何保留访问器且不污染原对象

问题根因

  • 扩展运算符...和Object.assign的默认行为都是读取源对象可枚举自有属性的值,而非复制属性的完整描述符:你解构parent时实际是调用var1的getter拿到当前值20,给child生成了一个普通数据属性var1,完全丢失了原有的getter/setter定义
  • 你用Object.assign会修改parent是因为用法错误:把parent作为了第一个参数(赋值目标),自然会把后续对象的属性写到parent上

解决方案

方案1:基于原型继承实现访问器复用(最简洁)

用Object.create指定parent为child的原型,child会自动继承原型上的var1访问器,自身新增的var2完全不会影响parent:

let val = 10;

let parent = {
  set var1(_val) {
    val = _val;
  },
  get var1() {
    return val;
  }
}

console.log(parent.var1); // 10
parent.var1 = 20;
console.log(parent.var1); // 20

// 以parent为原型创建新对象,再给自身加var2属性
let child = Object.create(parent);
child.var2 = 1;

parent.var1 = 30;
child.var1 = 40;
console.log(parent.var1, child.var1); // 输出 40 40,符合预期
// 验证parent不会被新增var2属性
console.log(parent.var2); // undefined

方案2:复制访问器描述符到child自身(无原型链依赖)

如果不需要原型继承,直接把parent的属性描述符完整复制到新对象,再新增var2即可:

let val = 10;

let parent = {
  set var1(_val) {
    val = _val;
  },
  get var1() {
    return val;
  }
}

console.log(parent.var1); // 10
parent.var1 = 20;
console.log(parent.var1); // 20

// 先复制parent的所有属性描述符到空对象,再新增var2
let child = Object.defineProperties({}, Object.getOwnPropertyDescriptors(parent));
child.var2 = 1;

parent.var1 = 30;
child.var1 = 40;
console.log(parent.var1, child.var1); // 输出 40 40,符合预期
// 验证parent不会被新增var2属性
console.log(parent.var2); // undefined

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:36:04