JavaScript能否按引用复制对象原始类型属性并动态创建get/set方法?
实现新对象属性与原对象同步更新的方案
完全可以动态生成对应的get/set方法,你原先用扩展运算符的写法只是把原对象的属性值浅拷贝到新对象,二者没有关联,自然做不到同步更新。下面是两种可直接使用的实现方案:
方案1:基于Object.defineProperty动态生成访问器
兼容性好,支持ES5及以上环境,适合属性固定、不需要响应源对象后续新增属性的场景:
const obj1 = { a: 1 }; const obj2 = { b: 2 }; // 定义新对象属性和对应来源对象的映射 const propSourceMap = { a: obj1, b: obj2 }; const newObj = {}; // 遍历映射表动态为每个属性生成get/set Object.keys(propSourceMap).forEach(propKey => { Object.defineProperty(newObj, propKey, { get() { // 读取时直接返回源对象对应属性的值 return propSourceMap[propKey][propKey]; }, set(newVal) { // 赋值时直接修改源对象对应属性 propSourceMap[propKey][propKey] = newVal; }, enumerable: true, // 保证属性可被遍历,和普通对象行为一致 configurable: true }); }); // 测试效果 newObj.a = 3; console.log(obj1.a); // 输出 3,符合预期 newObj.b = 4; console.log(obj2.b); // 输出 4
方案2:基于Proxy实现自动属性同步
更灵活不需要提前遍历属性,源对象后续新增的属性也能自动关联,适合属性动态变化的场景,需要环境支持ES6及以上:
const obj1 = { a: 1 }; const obj2 = { b: 2 }; // 按查找优先级排列源对象,靠前的对象优先匹配属性 const sourceList = [obj1, obj2]; const newObj = new Proxy({}, { get(target, prop) { // 查找第一个包含当前属性的源对象 const matchedSource = sourceList.find(source => Object.prototype.hasOwnProperty.call(source, prop) ); return matchedSource ? matchedSource[prop] : target[prop]; }, set(target, prop, value) { const matchedSource = sourceList.find(source => Object.prototype.hasOwnProperty.call(source, prop) ); if (matchedSource) { // 源对象存在该属性则修改源对象 matchedSource[prop] = value; return true; } // 源对象不存在的属性直接挂载到代理对象本身 target[prop] = value; return true; } }); // 测试效果 newObj.a = 3; console.log(obj1.a); // 输出 3 // 源对象后续新增属性也可以同步 obj1.c = 5; console.log(newObj.c); // 输出 5 newObj.c = 6; console.log(obj1.c); // 输出 6
内容的提问来源于stack exchange,提问作者Tovarish
相关产品推荐
相关产品推荐

