不要使用 Object.assign() 进行深层次对象合并

在前端开发中,经常需要将两个或多个对象合并成一个新的对象。对于浅层次对象,可以使用 Object.assign() 方法来实现对象合并。然而,当涉及到深层次对象合并时,Object.assign() 方法可能会出现一些问题。本文将探讨这些问题,并提供一些替代方法来进行深层次对象合并。

问题

当使用 Object.assign() 方法进行深层次对象合并时,可能会遇到以下问题:

1. 对象属性被覆盖

当两个对象具有相同的属性时,Object.assign() 方法会将后一个对象的属性值覆盖前一个对象的属性值。例如:

const obj1 = {
  a: {
    b: 1
  }
};

const obj2 = {
  a: {
    c: 2
  }
};

const newObj = Object.assign({}, obj1, obj2);

console.log(newObj); // { a: { c: 2 } }

我们期望得到的结果是 { a: { b: 1, c: 2 } },但实际上得到的结果是 { a: { c: 2 } },因为 Object.assign() 方法只会将后一个对象的属性值赋给前一个对象的同名属性。

2. 对象属性丢失

当对象属性的值为 null 或 undefined 时,Object.assign() 方法会将这些属性丢失。例如:

const obj1 = {
  a: null
};

const obj2 = {
  a: {
    b: 1
  }
};

const newObj = Object.assign({}, obj1, obj2);

console.log(newObj); // { a: { b: 1 } }

我们期望得到的结果是 { a: null },但实际上得到的结果是 { a: { b: 1 } },因为 Object.assign() 方法会将 null 或 undefined 值的属性丢失。

3. 对象属性为对象

当对象属性的值为对象时,Object.assign() 方法只会将该对象的引用赋给目标对象的属性,而不是将该对象的属性递归地合并到目标对象的属性中。例如:

const obj1 = {
  a: {
    b: 1
  }
};

const obj2 = {
  a: {
    c: 2
  }
};

const newObj = Object.assign({}, obj1, obj2);

console.log(newObj); // { a: { c: 2 } }
console.log(newObj.a === obj1.a); // true
console.log(newObj.a === obj2.a); // false

我们期望得到的结果是 { a: { b: 1, c: 2 } },但实际上得到的结果是 { a: { c: 2 } },因为 Object.assign() 方法只会将对象的引用赋给目标对象的属性。

解决方案

为了避免上述问题,我们可以使用一些替代方法来进行深层次对象合并。

1. Lodash 的 merge 方法

Lodash 是一个流行的 JavaScript 实用程序库,其中包含了许多有用的方法,包括 merge() 方法。merge() 方法可以递归地合并对象的属性。例如:

const _ = require('lodash');

const obj1 = {
  a: {
    b: 1
  }
};

const obj2 = {
  a: {
    c: 2
  }
};

const newObj = _.merge({}, obj1, obj2);

console.log(newObj); // { a: { b: 1, c: 2 } }

2. JSON.parse() 和 JSON.stringify() 方法

另一个方法是使用 JSON.parse()JSON.stringify() 方法来进行深层次对象合并。首先,将对象转换为 JSON 字符串,然后使用 JSON.parse() 方法将其转换回对象。在合并对象时,可以将两个对象转换为 JSON 字符串,然后使用 JSON.parse() 方法将其合并,最后再使用 JSON.stringify() 方法将其转换回 JSON 字符串。例如:

const obj1 = {
  a: {
    b: 1
  }
};

const obj2 = {
  a: {
    c: 2
  }
};

const newObj = JSON.parse(JSON.stringify(obj1));
JSON.parse(JSON.stringify(obj2), function(key, value) {
  if (newObj[key]) {
    Object.assign(newObj[key], value);
  } else {
    newObj[key] = value;
  }
});

console.log(newObj); // { a: { b: 1, c: 2 } }

总结

在进行深层次对象合并时,不要使用 Object.assign() 方法,因为它可能会出现一些问题。相反,可以使用 Lodash 的 merge() 方法或者使用 JSON.parse()JSON.stringify() 方法来进行深层次对象合并。这些方法可以避免出现对象属性被覆盖、对象属性丢失以及对象属性为对象时的问题。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65c20379add4f0e0ffbfd793