把两个对象进行合并,传入的对象中属性值有值,就用传入的对象。若传入的对象中,属性值没有值,或没有属性值,则用默认值。
let inputObj = {
people: {
name: 'jack',
age: 30,
},
car: {
color: 'black',
logo: 'bmw',
power: {
energy: 'fuel',
driveSystem: '4x4',
},
},
nationality: 'china'
};
let defaultObj = {
people: {
name: '',
age: 18,
},
car: {
color: 'white',
logo: 'vw',
power: {
type: 'suv',
energy: 'fuel',
driveSystem: '2',
},
},
nationality: 'earth'
};
代码如下:
export function mergeObjects(inputObject: any, defaultObject: any) {
let mergedObject = {};
// 遍历默认对象中的字段
for (let key in defaultObject) {
// eslint-disable-next-line no-prototype-builtins
if (defaultObject.hasOwnProperty(key)) {
// 检查inputObject中是否有这个key
// eslint-disable-next-line no-prototype-builtins
if (inputObject.hasOwnProperty(key)) {
// 如果两个对象的值都是对象类型,则递归合并它们
if (typeof defaultObject[key] === 'object' && typeof inputObject[key] === 'object' && !Array.isArray(defaultObject[key]) && !Array.isArray(inputObject[key])) {
mergedObject[key] = mergeObjects(inputObject[key], defaultObject[key]);
} else {
mergedObject[key] = inputObject[key]; // 否则使用inputObject中的值
}
} else {
mergedObject[key] = defaultObject[key]; // 如果inputObject中没有这个key,则使用defaultObject中的值
}
}
}
// 遍历inputObject中的字段,确保所有字段都包含在合并后的对象中
for (let key in inputObject) {
// eslint-disable-next-line no-prototype-builtins
if (inputObject.hasOwnProperty(key)) {
// eslint-disable-next-line no-prototype-builtins
if (!mergedObject.hasOwnProperty(key)) {
mergedObject[key] = inputObject[key];
}
}
}
return mergedObject;
};
说明一下,对于“hasOwnProperty”的作用,if (inputObject.hasOwnProperty(key))这一行的判断还是很有必要的,在合并对象函数中,使用 hasOwnProperty
确保只处理 inputObject
和 defaultObject
自身的属性,而不包括从原型链继承来的属性。