乐闻世界logo
搜索文章和话题

JS 如何动态合并两个对象的属性?

9 个月前提问
5 个月前修改
浏览次数54

6个答案

1
2
3
4
5
6

在JavaScript中,我们可以通过多种方式来动态合并两个对象的属性。其中最常用的方式是使用对象展开运算符(...)和Object.assign方法。下面分别举例说明这两种方法:

使用对象展开运算符(...

对象展开运算符允许我们以一种简洁的语法将一个对象中的所有可枚丽数字属性复制到另一个新的对象当中。以下是一个例子:

javascript
const object1 = { a: 1, b: 2 }; const object2 = { b: 3, c: 4 }; const mergedObject = { ...object1, ...object2 }; console.log(mergedObject); // 输出: { a: 1, b: 3, c: 4 }

在这个例子中,object1object2 被合并成 mergedObject。由于两个对象中都有属性 bobject2 中的 b 的值会覆盖object1b的值,因为它在展开操作中后面被指定。

使用Object.assign方法

Object.assign 方法用于将所有可枚举的自有属性从一个或多个源对象复制到目标对象,并返回修改后的目标对象。以下是一个例子:

javascript
const object1 = { a: 1, b: 2 }; const object2 = { b: 3, c: 4 }; const mergedObject = Object.assign({}, object1, object2); console.log(mergedObject); // 输出: { a: 1, b: 3, c: 4 }

在上面的例子中,我们首先创建了一个空对象 {} 作为目标对象,然后将 object1object2 中的属性复制到这个新对象中。和对象展开运算符一样,如果有重复的属性,后面的源对象会覆盖前面的源对象的同名属性。

其他注意点

动态合并对象时,还应该注意以下几点:

  1. 对象展开运算符和Object.assign都只会进行浅拷贝,这意味着如果对象属性是复杂类型(例如数组或另一个对象),合并后的对象将与源对象共享这个属性的引用。
  2. 当我们需要进行深拷贝合并时,可能需要使用递归策略或者使用库如lodash_.merge函数,以确保对象中嵌套的对象也被合并。
  3. 如果合并的对象中包含相同的属性,那么后面的对象的属性值会覆盖前面对象的属性值。

根据应用场景选择合适的合并策略非常重要,并且在处理大型或复杂的对象时,也要考虑性能和内存的影响。

2024年6月29日 12:07 回复

ECMAScript 2018 标准方法

您将使用对象传播

shell
let merged = {...obj1, ...obj2};

merged``obj1现在是和的并集obj2。中的属性obj2将覆盖 中的属性obj1

shell
/** There's no limit to the number of objects you can merge. * Later properties overwrite earlier properties with the same name. */ const allRules = {...obj1, ...obj2, ...obj3};

这里还有此语法的MDN 文档。如果您使用 babel,则需要@babel/plugin-proposal-object-rest-spread插件才能正常工作(该插件包含在ES2018@babel/preset-env中)。

ECMAScript 2015 (ES6) 标准方法

shell
/* For the case in question, you would do: */ Object.assign(obj1, obj2); /** There's no limit to the number of objects you can merge. * All objects get merged into the first object. * Only the object in the first argument is mutated and returned. * Later properties overwrite earlier properties with the same name. */ const allRules = Object.assign({}, obj1, obj2, obj3, etc);

(请参阅MDN JavaScript 参考


ES5 及更早版本的方法

shell
for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }

请注意,obj2如果obj1您仍想使用未修改的obj1.

如果你使用的框架在你的原型上到处乱七八糟,那么你必须使用像 之类的检查hasOwnProperty,但该代码适用于 99% 的情况。

示例函数:

shell
/** * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1 * @param obj1 * @param obj2 * @returns obj3 a new object based on obj1 and obj2 */ function merge_options(obj1,obj2){ var obj3 = {}; for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; } for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; } return obj3; }

另外:-检查此程序以查看 Object.assign 和 spread 语法对象文字之间的差异

2024年6月29日 12:07 回复

jQuery 也有一个实用程序: http: //api.jquery.com/jQuery.extend/

摘自 jQuery 文档:

shell
// Merge options object into settings object var settings = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" }; jQuery.extend(settings, options); // Now the content of settings object is the following: // { validate: true, limit: 5, name: "bar" }

上面的代码将改变名为的现有对象settings


如果您想创建一个新对象而不修改任何一个参数,请使用以下命令:

shell
var defaults = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" }; /* Merge defaults and options, without modifying defaults */ var settings = $.extend({}, defaults, options); // The content of settings variable is now the following: // {validate: true, limit: 5, name: "bar"} // The 'defaults' and 'options' variables remained the same.
2024年6月29日 12:07 回复

我在谷歌上搜索了合并对象属性的代码,最终找到了这里。然而,由于没有任何递归合并的代码,我自己编写了它。 (也许 jQuery 扩展是递归的?)无论如何,希望其他人也会发现它很有用。

(现在代码没有使用Object.prototype:)

代码

shell
/* * Recursively merge properties of two objects */ function MergeRecursive(obj1, obj2) { for (var p in obj2) { try { // Property in destination object set; update its value. if ( obj2[p].constructor==Object ) { obj1[p] = MergeRecursive(obj1[p], obj2[p]); } else { obj1[p] = obj2[p]; } } catch(e) { // Property in destination object not set; create it and set its value. obj1[p] = obj2[p]; } } return obj1; }

一个例子

shell
o1 = { a : 1, b : 2, c : { ca : 1, cb : 2, cc : { cca : 100, ccb : 200 } } }; o2 = { a : 10, c : { ca : 10, cb : 20, cc : { cca : 101, ccb : 202 } } }; o3 = MergeRecursive(o1, o2);

生成对象 o3 像

shell
o3 = { a : 10, b : 2, c : { ca : 10, cb : 20, cc : { cca : 101, ccb : 202 } } };
2024年6月29日 12:07 回复

请注意,underscore.js's extend-method在一行中执行此操作:

shell
_.extend({name : 'moe'}, {age : 50}); => {name : 'moe', age : 50}
2024年6月29日 12:07 回复

你的答案