我需要能够在运行时合并两个(非常简单)JavaScript对象。例如,我想:

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }

obj1.merge(obj2);

//obj1 now has three properties: food, car, and animal

是否有一种内置的方法来实现这一点?我不需要递归,也不需要合并函数,只需要平面对象上的方法。


当前回答

ES5兼容的原生单内胆:

var merged = [obj1, obj2].reduce(function(a, o) { for(k in o) a[k] = o[k]; return a; }, {})

其他回答

我刚开始使用JavaScript,所以如果我错了,请纠正我。

但如果可以合并任意数量的对象,不是更好吗?下面是我如何使用本机Arguments对象实现的。

关键在于,实际上可以向JavaScript函数传递任意数量的参数,而无需在函数声明中定义它们。如果不使用Arguments对象,就无法访问它们。

function mergeObjects() (
    var tmpObj = {};

    for(var o in arguments) {
        for(var m in arguments[o]) {
            tmpObj[m] = arguments[o][m];
        }
    }
    return tmpObj;
}

**使用Object.assign或排列合并对象很简单。。。操作员**

var obj1={food:“pizza”,car:“ford”}var obj2={animal:“狗”,car:“宝马”}var obj3={a:“a”}var mergedObj=对象赋值(obj1、obj2、obj3)//或使用Spread操作符(…)var mergedObj={…obj1,…obj2,…obj3}console.log(mergedObj);

对象从右向左合并,这意味着与右侧对象具有相同财产的对象将被覆盖。

在此示例中,obj2.car覆盖obj1.car

在一行代码中合并N个对象的财产

Object.assign方法是ECMAScript 2015(ES6)标准的一部分,它完全符合您的需要。(不支持IE)

var clone = Object.assign({}, obj);

assign()方法用于将所有可枚举自身财产的值从一个或多个源对象复制到目标对象。

阅读更多。。。

支持旧浏览器的polyfill:

if (!Object.assign) {
  Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(target) {
      'use strict';
      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }

      var to = Object(target);
      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i];
        if (nextSource === undefined || nextSource === null) {
          continue;
        }
        nextSource = Object(nextSource);

        var keysArray = Object.keys(nextSource);
        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}

在MooTools中,有Object.merge():

Object.merge(obj1, obj2);

JSON兼容JavaScript对象的合并

我鼓励使用和利用不修改原始源代码的非破坏性方法,“Object.assign”是一种破坏性的方法,而且它也不太适合生产,因为它在早期浏览器上停止工作,而且你没有办法用其他方法对它进行干净的修补。

无论采用何种解决方案,合并JS对象都将永远无法实现或不完整。但是,合并JSON兼容的兼容对象离能够编写一段简单且可移植的代码只有一步之遥。该代码是一种非破坏性方法,将一系列JS对象合并到一个返回的主对象中,该主对象包含所有唯一的属性名及其对应的值,这些属性名合成在一个主对象中用于预期目的。

考虑到MSIE8是第一个为JSON对象添加本地支持的浏览器,这是一种极大的解脱,重用现有技术始终是一个受欢迎的机会。

将代码限制为JSON兼容的标准对象,与其说是限制,不如说是优势,因为这些对象也可以通过互联网传输。当然,对于那些想要更深入的向后兼容性的人来说,总是有一个json插件。,其方法可以很容易地分配给外部代码中的JSON变量,而无需修改或重写正在使用的方法。

function Merge( ){
    var a = [].slice.call( arguments ), i = 0;
        while( a[i] )a[i] = JSON.stringify( a[i++] ).slice( 1,-1 );
        return JSON.parse( "{"+ a.join() +"}" );
    }

(当然,人们总是可以给它取一个更有意义的名字,我还没有决定;应该把它命名为JSONmerge)

用例:

var master = Merge( obj1, obj2, obj3, ...objn );

现在,与Object.assign相反,这将使所有对象保持不变,并保持其原始状态(以防您做错了什么,需要重新排序合并对象,或者在再次合并之前能够将它们单独用于其他操作)。

Merge参数的数量也仅受参数长度限制[这是巨大的]的限制。本机支持的JSON parse/stringify已经进行了机器优化,这意味着:它应该比任何脚本形式的JS循环都快。对给定参数的迭代是使用while完成的,while被证明是JS中最快的循环。

简单地提一下我们已经知道的事实,即唯一对象标签(键)的重复财产将被包含相同键标签的后一个对象覆盖,这并不有害,这意味着您可以通过简单地对参数列表进行排序或重新排序来控制哪个属性将取代前一个属性。以及获得一个干净且更新的主对象而无重复作为最终输出的好处。

;var obj1={a:1},obj2={b:2},obj3={c:3};函数合并(){var a=[].slice.call(参数),i=0;而(a[i])a[i]=JSON.stringify(a[i++]).slice(1,-1);return JSON.parse(“{”+a.join()+“}”);};var master=合并(obj1、obj2、obj3);console.log(JSON.stringify(master));