如何通过引用将多个对象的属性合并到另一个对象?
实现对象属性的引用式合并
要实现修改合并后对象的属性时同步修改原对象,且不使用嵌套结构,你可以通过定义属性的getter和setter或者使用Proxy代理对象来实现,这两种方式都能让合并后的对象属性直接关联到原对象的属性。
方法一:用Object.defineProperty绑定Getter/Setter
通过给合并对象的每个属性定义getter和setter,让属性的读写操作直接映射到原对象的对应属性:
function mergeByReference(target, ...sources) { sources.forEach(source => { Object.keys(source).forEach(key => { Object.defineProperty(target, key, { get() { return source[key]; }, set(value) { source[key] = value; }, enumerable: true, configurable: true }); }); }); return target; } // 使用示例 const objectA = {"key1" : 1, "key2" : 2, "key3" : 3}; const objectB = {"key4" : 4, "key5" : 5, "key6" : 6}; const bigObject = mergeByReference({}, objectA, objectB); bigObject["key1"] = 50; console.log(bigObject["key1"]); // 输出 50 console.log(objectA["key1"]); // 输出 50(同步修改原对象) bigObject["key4"] = 100; console.log(bigObject["key4"]); // 输出 100 console.log(objectB["key4"]); // 输出 100
说明:
- 遍历每个源对象的属性,给目标对象(
bigObject)的对应属性绑定getter和setter:读取属性时返回原对象的值,修改属性时同步更新原对象。 enumerable: true确保属性可以被Object.keys()或for...in遍历到;configurable: true允许后续修改该属性的定义。- 如果多个源对象存在相同键,后处理的源对象会覆盖前一个的属性绑定。
方法二:使用Proxy代理对象
通过创建Proxy对象,拦截所有属性的读写操作,动态关联到原对象的属性:
function mergeByReferenceProxy(...sources) { return new Proxy({}, { get(target, prop) { // 查找第一个包含目标属性的源对象 for (const source of sources) { if (prop in source) { return source[prop]; } } return undefined; }, set(target, prop, value) { // 修改第一个包含目标属性的源对象的属性 for (const source of sources) { if (prop in source) { source[prop] = value; return true; } } // 若属性不存在于任何源对象,可选择添加到代理目标(可选逻辑) target[prop] = value; return true; }, ownKeys(target) { // 返回所有源对象的键(去重) const keys = new Set(); sources.forEach(source => Object.keys(source).forEach(key => keys.add(key))); return Array.from(keys); } }); } // 使用示例 const objectA = {"key1" : 1, "key2" : 2, "key3" : 3}; const objectB = {"key4" : 4, "key5" : 5, "key6" : 6}; const bigObject = mergeByReferenceProxy(objectA, objectB); bigObject.key1 = 50; console.log(bigObject.key1); // 输出 50 console.log(objectA.key1); // 输出 50 bigObject.key5 = 200; console.log(bigObject.key5); // 输出 200 console.log(objectB.key5); // 输出 200
说明:
- Proxy会拦截合并对象的所有属性操作,读取时自动查找对应源对象的属性,修改时同步更新原对象。
- 无需预先遍历源对象定义属性,所有操作都是动态的,适合源对象属性可能动态变化的场景。
- 重复键的处理逻辑是优先使用第一个出现该键的源对象(可根据需求调整遍历顺序)。
内容的提问来源于stack exchange,提问作者Robert M.
相关产品推荐
相关产品推荐

