问两个深层对象如何替换合并?
总所周知JavaScript中的对象合并就很简单了,可以使用Object.assign() 这种方法进行合并,还可以使用
...
对象拓展运算符进行拓展。数组可以使用Array.prototype.concat() 数组合并又或者使用...
数组拓展运算符 进行合并,但往往这些只能合并简单的类型数据,对于合并深层的数据类型比如嵌套对象如何进行合并?对于数组对象合并就不再说了,那么如何替换呢,对象浅一点的对象可以进行覆盖,数组对象却不能,那么对于深层的对象或者数组对象如何替换呢?
解决方案
- 使用loadsh中的merge方法
- 自定义一个
hooks
工具类函数
代码实现
- 使用
loadsh
中的merge
方法
_.merge(object, [sources])
该方法类似
_.assign
, 除了它递归合并sources
来源对象自身和继承的可枚举属性到object
目标对象。如果目标值存在,被解析为undefined
的sources
来源对象属性将被跳过。数组和普通对象会递归合并,其他对象和值会被直接分配覆盖。源对象从从左到右分配。后续的来源对象属性会覆盖之前分配的属性。Note: 这方法会改变对象
object
.添加版本
0.5.0
参数
object
(Object) : 目标对象。[sources]
(...Object) : 来源对象。返回
(Object) : 返回
object
.
var object = {
'a': [{ 'b': 2 }, { 'd': 4 }]
};
var other = {
'a': [{ 'c': 3 }, { 'e': 5 }]
};
_.merge(object, other);
// => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
- 自定义一个hooks工具类函数
/**
* Simple object check.
* @param item
* @returns {boolean}
*/
// 判断对应的类型
export function typeChecked(arg: any) {
const len = Object.prototype.toString.call(arg).substring(8).split('').length
return Object.prototype.toString.call(arg).substring(8).split('').slice(0, len - 1).join('')
}
/**
* Deep merge two objects.
* @param target
* @param ...sources
*/
export function mergeDeep(target, ...sources) {
if (!sources.length) return target;
const source = sources.shift();
if (typeChecked(target)==='Object' && typeChecked(source)==='Object') {
for (const key in source) {
if (typeChecked(source[key])==='Object') {
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 } } });
// or
const merged = mergeDeep({a: 1}, { b : { c: { d: { e: 12345}}}});
console.dir(merged); // { a: 1, b: { c: { d: [Object] } } }
总结
世上无难事,只要肯放弃,加油你还年轻!!!