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
相关产品推荐
相关产品推荐

