如何让复制后的JavaScript对象修改b属性时自动同步更新c属性?
实现属性联动更新的解决方案
嘿,这个问题的关键在于你一开始给c赋值的方式是静态的——它只是把a.b当时的数值存了下来,并不是和b绑定在一起。要实现修改b后c自动同步,我们需要把c改成动态计算的属性,下面给你两种实用的方案:
方案1:使用Getter属性(最简洁轻量)
直接在原对象中用ES6的getter语法定义c,这样每次访问c时都会动态返回当前b的值:
// 原文件中的对象定义 let a = { b: 1, // 定义getter,每次访问c都会执行这个函数 get c() { return this.b; } };
复制对象的注意事项
如果直接用Object.assign({}, a),getter会被执行一次,把当前b的值作为静态属性赋值给新对象,这样复制后的c又变成固定值了。要保留动态联动的特性,我们需要复制属性的描述符,而不是只复制值:
// 引入对象后,用属性描述符复制 const a = require('./a.js'); // 获取原对象所有属性的描述信息(包括getter定义) const descriptors = Object.getOwnPropertyDescriptors(a); // 把描述符应用到新对象上 const copiedObject = Object.defineProperties({}, descriptors); copiedObject.b = 2; console.log(copiedObject.c); // 输出2,完美同步
方案2:使用Proxy(更灵活的响应式)
如果你的需求更复杂(比如多个属性之间有联动逻辑),可以用ES6的Proxy来拦截属性访问:
// 原文件中的对象定义 let a = new Proxy({ b: 1 }, { get(target, prop) { // 当访问c时,返回当前b的值 if (prop === 'c') { return target.b; } // 其他属性正常返回 return target[prop]; } });
复制Proxy对象
复制时需要给新对象也套一层Proxy,或者直接复制目标对象后再包裹:
const a = require('./a.js'); // 先复制原Proxy的目标对象,再套一层同样的Proxy逻辑 const copiedObject = new Proxy(Object.assign({}, a), { get(target, prop) { if (prop === 'c') { return target.b; } return target[prop]; } }); copiedObject.b = 2; console.log(copiedObject.c); // 输出2
总结
- 优先用Getter属性,它语法简洁、性能好,适合简单的属性联动场景
- 如果需要复杂的响应式逻辑,再考虑用Proxy
- 复制对象时一定要注意保留动态属性的定义,而不是只复制静态值
内容的提问来源于stack exchange,提问作者Daniel Kormos
相关产品推荐
相关产品推荐

