981377660LMT / ts

ts学习
6 stars 1 forks source link

Object.assign 原地更新属性注意点 #455

Open 981377660LMT opened 7 months ago

981377660LMT commented 7 months ago

防止同名属性被覆盖(希望是合并而非覆盖)

例如 const obj1 = {a:{b:1,c:2}} 和 const obj2 = {a:{d:3}} 这种情况 如果你希望合并嵌套的对象属性,你需要使用深度合并。这通常涉及到递归地检查每个属性是否是对象,然后合并或复制属性。这里有一个简单的例子:

type AnyObject = { [key: string]: any };

function isObject(item: any): item is AnyObject {
  return (item && typeof item === 'object' && !Array.isArray(item));
}

function deepMerge(target: AnyObject, source: AnyObject): AnyObject {
  let output: AnyObject = Object.assign({}, target);
  if (isObject(target) && isObject(source)) {
    Object.keys(source).forEach(key => {
      if (isObject(source[key])) {
        if (!(key in target))
          Object.assign(output, { [key]: source[key] });
        else
          output[key] = deepMerge(target[key], source[key]);
      } else {
        Object.assign(output, { [key]: source[key] });
      }
    });
  }
  return output;
}

let obj1 = { a: { b: 1, c: 2 } };
let obj2 = { a: { d: 3 } };
let obj3 = deepMerge(obj1, obj2);
console.log(obj3); // 输出:{ a: { b: 1, c: 2, d: 3 } }

在这个例子中,deepMerge函数会递归地检查每个属性是否是对象。如果是对象,就递归地合并属性;如果不是对象,就直接复制属性。