合并对象(关联数组)

Wil*_*elm 146 javascript object

在JavaScript中合并两个关联数组的最佳/标准方法是什么?每个人都是通过滚动自己的for循环来做到的吗?

kul*_*pae 199

用jquery你可以打电话 $.extend

var obj1 = {a: 1, b: 2};
var obj2 = {a: 4, c: 110};

var obj3 = $.extend(obj1, obj2); 

obj1 == obj3 == {a: 4, b: 2, c: 110} // Pseudo JS
Run Code Online (Sandbox Code Playgroud)

(assoc.数组是js中的对象)

看这里:http://api.jquery.com/jQuery.extend/


编辑:像rymo建议的那样,最好这样做:

obj3 = $.extend({}, obj1, obj2); 
obj3 == {a: 4, b: 2, c: 110}
Run Code Online (Sandbox Code Playgroud)

因为这里obj1(和obj2)保持不变.


edit2:在2018年,做到这一点的方法是通过Object.assign:

var obj3 = Object.assign({}, obj1, obj2); 
obj3 === {a: 4, b: 2, c: 110} // Pseudo JS
Run Code Online (Sandbox Code Playgroud)

如果使用ES6,可以使用Spread Operator实现:

const obj3 = { ...obj1, ...obj2 };
Run Code Online (Sandbox Code Playgroud)

  • 或者为了避免混淆`obj1`,使用空对象作为目标:`$ .extend({},obj1,obj2)` (53认同)
  • 对于现代浏览器,请使用Object.assign()通过@manfred检查解决方案,如果您尚未使用该库,则它不依赖JQuery。 (2认同)

Man*_*red 61

现在在2016年我会说最好的/标准的方式是Object.assign()
Pure Javascript.不需要jQuery.

obj1 = {a: 1, b: 2};
obj2 = {a: 4, c: 110};
obj3 = Object.assign({},obj1, obj2);  // Object {a: 4, b: 2, c: 110}
Run Code Online (Sandbox Code Playgroud)

更多信息,示例和polyfill:https:
//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign


Jon*_*and 49

这就是Prototype的作用:

Object.extend = function(destination, source) {
    for (var property in source) {
        if (source.hasOwnProperty(property)) {
            destination[property] = source[property];
        }
    }
    return destination;
};
Run Code Online (Sandbox Code Playgroud)

被称为,例如:

var arr1?= { robert: "bobby", john: "jack" };
var arr2 = { elizabeth: "liz", jennifer: "jen" };

var shortnames = Object.extend(arr1,arr2);
Run Code Online (Sandbox Code Playgroud)

编辑:添加hasOwnProperty()检查正确由bucabay在评论中指出

  • 您需要测试source.hasOwnProperty(property)以确保只复制直接属性.实际上,这可能会复制所有属性,包括从Object.prototype派生的属性 (6认同)

小智 22

把事情简单化...

function mergeArray(array1,array2) {
  for(item in array1) {
    array2[item] = array1[item];
  }
  return array2;
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以检查hasOwnProperty以避免复制`arrau1.prototype`上的任何属性 (6认同)
  • +1不适合像jQuery这样的库.谢谢 :) (4认同)

Mik*_*Kay 14

Underscore也有一个扩展方法:

将源对象中的所有属性复制到目标对象.它是有序的,因此最后一个源将覆盖先前参数中相同名称的属性.

_.extend(destination, *sources) 

_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}
Run Code Online (Sandbox Code Playgroud)


Ale*_*lli 7

dojo中,2个对象/数组"合并"将是lang.mixin(destination, source)- 您还可以将多个源混合到一个目标等中 - 有关详细信息,请参阅mixin函数的参考.


ken*_*bec 6

如果名称相同但值不是,是否要覆盖属性?

你想永久改变一个原始对象,

或者你想要一个新的合并对象返回?

function mergedObject(obj1, obj2, force){
    for(var p in obj1) this[p]= obj1[p];
    for(var p in obj2){
        if(obj2.hasOwnProperty(p)){
            if(force || this[p]=== undefined) this[p]= obj2[p];
            else{
                n= 2;
                while(this[p+n]!== undefined)++n;
                this[p+n]= obj2[p];
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Cod*_*ody 6

滚动你自己的扩展/混合功能

function extend(objects) {
    var args
        , first = Array.prototype.slice.call(arguments, 0, 1)[0]
        , second;

    if (arguments.length > 1) {
        second = Array.prototype.splice.call(arguments, 1, 1)[0];
        for (var key in second) {
            first[key] = second[key];
        }
        args = Array.prototype.slice.call(arguments, 0);
        return extend.apply(this, args);
    }

    return first;
}
Run Code Online (Sandbox Code Playgroud)

...

var briansDirections = {
    step1: 'Remove pastry from wrapper.',
    step2: 'Place pastry toaster.',
    step3: 'Remove pastry from toaster and enjoy.',
};
extend(briansDirections, { step1: 'Toast Poptarts' }, { step2: 'Go ahead, toast \'em' }, { step3: 'Hey, are you sill reading this???' });
Run Code Online (Sandbox Code Playgroud)

...

这只是延伸的图示的对象,递归.另请注意,此递归函数是TCO(Tail-Call Optimized),因为它的返回是对自身的最后一次调用.

此外,您可能需要目标属性.在这种情况下,你可能要凝聚基于对象id,quantity或其他财产.这种方法可能有一本关于它的小书,需要对象并置,并且可能变得非常复杂.我已经为此编写了一个小型库,可根据要求提供.

希望这可以帮助!


归档时间:

查看次数:

90064 次

最近记录:

6 年,9 月 前