如何进行深度合并而不是浅层合并?双管齐下对象.分配和对象传播只做浅合并。这个问题的一个例子是:// No object nestingconst x = { a: 1 }const y = { b: 1 }const z = { ...x, ...y } // { a: 1, b: 1 }输出就是你所期望的。然而,如果我尝试这样做:// Object nestingconst x = { a: { a: 1 } }const y = { a: { b: 1 } }const z = { ...x, ...y } // { a: { b: 1 } }而不是{ a: { a: 1, b: 1 } }你得到{ a: { b: 1 } }X被完全覆盖,因为扩展语法只有一个层次。这和Object.assign().有办法吗?
3 回答
繁星点点滴滴
TA贡献1803条经验 获得超3个赞
/** * Simple object check. * @param item * @returns {boolean} */export function isObject(item) { return (item && typeof item === 'object' && !Array.isArray(item));}/** * Deep merge two objects. * @param target * @param ...sources */export function mergeDeep(target, ...sources) { if (!sources.length) return target; const source = sources.shift(); if (isObject(target) && isObject(source)) { for (const key in source) { if (isObject(source[key])) { if (!target[key]) Object.assign(target, { [key]: {} }); mergeDeep(target[key], source[key]); } else { Object.assign(target, { [key]: source[key] }); } } } return mergeDeep(target, ...sources);}
mergeDeep(this, { a: { b: { c: 123 } } });// orconst merged = mergeDeep({a: 1}, { b : { c: { d: { e: 12345}}}}); console.dir(merged); // { a: 1, b: { c: { d: [Object] } } }
请注意,这将导致循环引用的无限递归。
慕容森
TA贡献1853条经验 获得超18个赞
您是调用getter来获取值,还是对属性描述符进行复制? 如果合并目标有一个setter(要么拥有属性,要么在它的原型链中)怎么办?您认为值已经存在还是调用setter来更新当前值? 您是调用自己的属性函数还是复制它们?如果它们是绑定函数或箭头函数,这取决于它们定义时作用域链中的某些内容? 如果它类似于DOM节点呢?当然,您不希望将其视为简单对象,而只是将其所有属性深度合并到 如何处理数组、映射或集合等“简单”结构?考虑他们-现在还是合并他们? 如何处理不可枚举的自身属性? 新的子树呢?简单地指定引用还是深克隆? 如何处理冻结/密封/不可扩展的对象?
Set
添加回答
举报
0/150
提交
取消