두 개의 JavaScript 객체의 속성을 동적으로 병합하려면 어떻게해야합니까?

StackOverflow https://stackoverflow.com/questions/171251

  •  05-07-2019
  •  | 
  •  

문제

런타임에 두 개의 (매우 간단한) JavaScript 객체를 병합 할 수 있어야합니다. 예를 들어 다음과 같이하고 싶습니다.

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

obj1.merge(obj2);

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

누구든지 이것에 대한 대본이 있거나이 작업을 수행하는 방법을 알고 있습니까? 재귀가 필요하지 않으며 평평한 물체의 메소드 만 병합 할 필요가 없습니다.

도움이 되었습니까?

해결책

ECMAScript 2018 표준 방법

당신은 사용할 것입니다 물체가 퍼졌습니다:

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

/** 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};

ECMAScript 2015 (ES6) 표준 방법

/* 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 이상을위한 방법

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

이것은 단순히 모든 속성을 추가합니다 obj2 에게 obj1 아직 수정되지 않은 것을 사용하고 싶다면 원하는 것이 아닐 수도 있습니다. obj1.

프로토 타입 전체에 걸친 프레임 워크를 사용하는 경우 수표로 더 멋진 점을 가져야합니다. hasOwnProperty, 그러나이 코드는 99%의 사례에 대해 작동합니다.

예제 기능 :

/**
 * 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;
}

다른 팁

jQuery는 또한 다음과 같은 유틸리티가 있습니다. http://api.jquery.com/jquery.extend/.

jQuery 문서에서 가져온 :

// 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.


당신이 만들고 싶다면 새로운 대상 어느 주장도 수정하지 않고 이것을 사용하십시오.

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.

그만큼 Harmony ECMAScript 2015 (ES6) 지정합니다 Object.assign 이것을 할 것입니다.

Object.assign(obj1, obj2);

현재 브라우저 지원입니다 나아지고 있습니다, 그러나 지원이없는 브라우저를 위해 개발중인 경우 폴리 필.

코드가 객체 속성을 병합하기 위해 검색하고 여기에 끝났습니다. 그러나 재귀 병합에 대한 코드가 없기 때문에 직접 썼습니다. (어쩌면 jQuery 확장은 재귀 적 BTW일까요?) 어쨌든 다른 사람도 유용 할 수 있기를 바랍니다.

(이제 코드가 사용되지 않습니다 Object.prototype :)

암호

/*
* 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;
}

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와 같은 생성을 생성합니다

o3 = {  a : 10,
        b : 2,
        c : {
          ca : 10,
          cb : 20,
          cc : { 
            cca : 101,
            ccb : 202 } } };

주목하십시오 underscore.js'에스 extend-방법 이것은 하나의 라이너에서 다음과 같습니다.

_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}

jQuery extend ()와 유사하게 동일한 기능이 있습니다. Angularjs:

// Merge the 'options' object into the 'settings' object
var settings = {validate: false, limit: 5, name: "foo"};
var options  = {validate: true, name: "bar"};
angular.extend(settings, options);

오늘은 물체를 합병해야 하며이 질문 (및 답변)이 저에게 많은 도움이되었습니다. 나는 몇 가지 답을 시도했지만 아무도 내 요구에 맞지 않았으므로 답을 결합하고 무언가를 추가하고 새로운 병합 기능을 생각해 냈습니다. 여기있어:

var merge = function() {
    var obj = {},
        i = 0,
        il = arguments.length,
        key;
    for (; i < il; i++) {
        for (key in arguments[i]) {
            if (arguments[i].hasOwnProperty(key)) {
                obj[key] = arguments[i][key];
            }
        }
    }
    return obj;
};

일부 예제 사용 :

var t1 = {
    key1: 1,
    key2: "test",
    key3: [5, 2, 76, 21]
};
var t2 = {
    key1: {
        ik1: "hello",
        ik2: "world",
        ik3: 3
    }
};
var t3 = {
    key2: 3,
    key3: {
        t1: 1,
        t2: 2,
        t3: {
            a1: 1,
            a2: 3,
            a4: [21, 3, 42, "asd"]
        }
    }
};

console.log(merge(t1, t2));
console.log(merge(t1, t3));
console.log(merge(t2, t3));
console.log(merge(t1, t2, t3));
console.log(merge({}, t1, { key1: 1 }));

당신이 사용할 수있는 물체 스프레드 특성- 3 단계 ecmascript 제안서.

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

const obj3 = { ...obj1, ...obj2 };
console.log(obj3);

주어진 솔루션을 확인하려면 수정해야합니다 source.hasOwnProperty(property) 에서 for..in 할당하기 전에 루프 - 그렇지 않으면, 당신은 거의 원하지 않는 전체 프로토 타입 체인의 특성을 복사하게됩니다 ...

N 객체의 속성을 한 줄의 코드를 병합

an Object.assign 방법은 ECMAScript 2015 (ES6) 표준의 일부이며 필요한 것을 정확하게 수행합니다. (IE 지원되지 않음)

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

Object.Assign () 메소드는 하나 이상의 소스 개체에서 대상 개체로 열거 가능한 모든 자체 속성의 값을 복사하는 데 사용됩니다.

더 읽기 ...

그만큼 폴리 필 구형 브라우저를 지원하려면 :

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;
    }
  });
}

다음 두 가지는 아마도 좋은 출발점 일 것입니다. Lodash는 또한 이러한 특별한 요구에 맞는 커스터마이저 기능을 가지고 있습니다!

_.extend (http://underscorejs.org/#extend)
_.merge (https://lodash.com/docs#merge)

그건 그렇고, 당신이하는 일은 합병하지 않고 속성을 덮어 쓰는 것입니다 ...

이것이 JavaScript 객체 영역이 실제로 병합 된 방식입니다. to 물체 자체가 아닌 객체는 from. 다른 모든 것이 될 것입니다 정말 합병되었습니다. 물론이 동작을 변경하여 to[n] is undefined, 등...:

var realMerge = function (to, from) {

    for (n in from) {

        if (typeof to[n] != 'object') {
            to[n] = from[n];
        } else if (typeof from[n] == 'object') {
            to[n] = realMerge(to[n], from[n]);
        }
    }
    return to;
};

용법:

var merged = realMerge(obj1, obj2);

여기 내 찌르레입니다

  1. 깊은 병합을 지원합니다
  2. 인수를 돌연변이하지 않습니다
  3. 많은 논쟁을 취합니다
  4. 객체 프로토 타입을 확장하지 않습니다
  5. 다른 라이브러리에 의존하지 않습니다 (jQuery, mootools, aUNDSCORE.JS, 등.)
  6. HasownProperty 수표가 포함되어 있습니다
  7. 짧은 :)

    /*
        Recursively merge properties and return new object
        obj1 &lt;- obj2 [ &lt;- ... ]
    */
    function merge () {
        var dst = {}
            ,src
            ,p
            ,args = [].splice.call(arguments, 0)
        ;
    
        while (args.length > 0) {
            src = args.splice(0, 1)[0];
            if (toString.call(src) == '[object Object]') {
                for (p in src) {
                    if (src.hasOwnProperty(p)) {
                        if (toString.call(src[p]) == '[object Object]') {
                            dst[p] = merge(dst[p] || {}, src[p]);
                        } else {
                            dst[p] = src[p];
                        }
                    }
                }
            }
        }
    
       return dst;
    }
    

예시:

a = {
    "p1": "p1a",
    "p2": [
        "a",
        "b",
        "c"
    ],
    "p3": true,
    "p5": null,
    "p6": {
        "p61": "p61a",
        "p62": "p62a",
        "p63": [
            "aa",
            "bb",
            "cc"
        ],
        "p64": {
            "p641": "p641a"
        }
    }
};

b = {
    "p1": "p1b",
    "p2": [
        "d",
        "e",
        "f"
    ],
    "p3": false,
    "p4": true,
    "p6": {
        "p61": "p61b",
        "p64": {
            "p642": "p642b"
        }
    }
};

c = {
    "p1": "p1c",
    "p3": null,
    "p6": {
        "p62": "p62c",
        "p64": {
            "p643": "p641c"
        }
    }
};

d = merge(a, b, c);


/*
    d = {
        "p1": "p1c",
        "p2": [
            "d",
            "e",
            "f"
        ],
        "p3": null,
        "p5": null,
        "p6": {
            "p61": "p61b",
            "p62": "p62c",
            "p63": [
                "aa",
                "bb",
                "cc"
            ],
            "p64": {
                "p641": "p641a",
                "p642": "p642b",
                "p643": "p641c"
            }
        },
        "p4": true
    };
*/

Object.Assign ()

ECMAScript 2015 (ES6)

이것은 ECMAScript 2015 (ES6) 표준의 일부인 새로운 기술입니다. 이 기술의 사양은 완료되었지만 다양한 브라우저에서 사용 및 구현 상태에 대한 호환성 테이블을 확인하십시오.

Object.Assign () 메소드는 하나 이상의 소스 개체에서 대상 개체로 열거 가능한 모든 자체 속성의 값을 복사하는 데 사용됩니다. 대상 객체를 반환합니다.

var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, target object itself is changed.

사용할 수없는 객체의 경우 사용할 수 있습니다 JSON:

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

objMerge = JSON.stringify(obj1) + JSON.stringify(obj2);

// {"food": "pizza","car":"ford"}{"animal":"dog","car":"chevy"}

objMerge = objMerge.replace(/\}\{/, ","); //  \_ replace with comma for valid JSON

objMerge = JSON.parse(objMerge); // { food: 'pizza', animal: 'dog', car: 'chevy'}
// Of same keys in both objects, the last object's value is retained_/

이 예에서 "} {" 발생해서는 안됩니다 문자열 안에!

이 작업을 수행하는 가장 좋은 방법은 Object.DefineProperty를 사용하여 활성화 할 수없는 적절한 속성을 추가하는 것입니다.

이렇게하면 객체 .prototype.extend로 속성을 만들면 새로 만든 "확장"을받지 않고도 객체 속성을 반복 할 수 있습니다.

바라건대 이것은 도움이됩니다 :

Object.defineProperty(Object.prototype, "extend", {
    enumerable: false,
    value: function(from) {
        var props = Object.getOwnPropertyNames(from);
        var dest = this;
        props.forEach(function(name) {
            if (name in dest) {
                var destination = Object.getOwnPropertyDescriptor(from, name);
                Object.defineProperty(dest, name, destination);
            }
        });
        return this;
    }
});

일단 작업을 수행하면 다음을 수행 할 수 있습니다.

var obj = {
    name: 'stack',
    finish: 'overflow'
}
var replacement = {
    name: 'stock'
};

obj.extend(replacement);

방금 여기에 블로그 게시물을 썼습니다. http://onemoreordigit.com/post/1527191998/extending-objects-in-1ode-js

jQuery를 사용할 수 있습니다 extend

var obj1 = { val1: false, limit: 5, name: "foo" };
var obj2 = { val2: true, name: "bar" };

jQuery.extend(obj1, obj2);

지금 obj1 모든 값을 포함합니다 obj1 그리고 obj2

라이브러리가 있습니다 deepmerge ~에 github: 그것은 약간의 견인력을 얻고있는 것 같습니다. 두 가지를 통해 사용할 수있는 독립형입니다 NPM 그리고 Bower 패키지 관리자.

나는 답변에서 복사 코드 대신 이것을 사용하거나 개선하는 경향이 있습니다.

원기 이것을 가지고 있습니다 :

Object.extend = function(destination,source) {
    for (var property in source)
        destination[property] = source[property];
    return destination;
}

obj1.extend(obj2) 당신이 원하는 것을 할 것입니다.

누군가가 사용중인 경우 Google 폐쇄 라이브러리:

goog.require('goog.object');
var a = {'a': 1, 'b': 2};
var b = {'b': 3, 'c': 4};
goog.object.extend(a, b);
// Now object a == {'a': 1, 'b': 3, 'c': 4};

어레이에 대해 유사한 도우미 기능이 있습니다:

var a = [1, 2];
var b = [3, 4];
goog.array.extend(a, b); // Extends array 'a'
goog.array.concat(a, b); // Returns concatenation of array 'a' and 'b'

나는 David Coallier의 방법을 확장했습니다.

  • 여러 객체를 병합 할 가능성이 추가되었습니다
  • 깊은 물체를 지원합니다
  • 재정의 매개 변수 (마지막 매개 변수가 부울 인 경우 감지)

재정의가 False 인 경우 속성이 재정의되지 않지만 새로운 속성이 추가됩니다.

사용법 : obj.merge (병합 ... [, 재정의]);

내 코드는 다음과 같습니다.

Object.defineProperty(Object.prototype, "merge", {
    enumerable: false,
    value: function () {
        var override = true,
            dest = this,
            len = arguments.length,
            props, merge, i, from;

        if (typeof(arguments[arguments.length - 1]) === "boolean") {
            override = arguments[arguments.length - 1];
            len = arguments.length - 1;
        }

        for (i = 0; i < len; i++) {
            from = arguments[i];
            if (from != null) {
                Object.getOwnPropertyNames(from).forEach(function (name) {
                    var descriptor;

                    // nesting
                    if ((typeof(dest[name]) === "object" || typeof(dest[name]) === "undefined")
                            && typeof(from[name]) === "object") {

                        // ensure proper types (Array rsp Object)
                        if (typeof(dest[name]) === "undefined") {
                            dest[name] = Array.isArray(from[name]) ? [] : {};
                        }
                        if (override) {
                            if (!Array.isArray(dest[name]) && Array.isArray(from[name])) {
                                dest[name] = [];
                            }
                            else if (Array.isArray(dest[name]) && !Array.isArray(from[name])) {
                                dest[name] = {};
                            }
                        }
                        dest[name].merge(from[name], override);
                    } 

                    // flat properties
                    else if ((name in dest && override) || !(name in dest)) {
                        descriptor = Object.getOwnPropertyDescriptor(from, name);
                        if (descriptor.configurable) {
                            Object.defineProperty(dest, name, descriptor);
                        }
                    }
                });
            }
        }
        return this;
    }
});

예 및 테스트 케이스 :

function clone (obj) {
    return JSON.parse(JSON.stringify(obj));
}
var obj = {
    name : "trick",
    value : "value"
};

var mergeObj = {
    name : "truck",
    value2 : "value2"
};

var mergeObj2 = {
    name : "track",
    value : "mergeObj2",
    value2 : "value2-mergeObj2",
    value3 : "value3"
};

assertTrue("Standard", clone(obj).merge(mergeObj).equals({
    name : "truck",
    value : "value",
    value2 : "value2"
}));

assertTrue("Standard no Override", clone(obj).merge(mergeObj, false).equals({
    name : "trick",
    value : "value",
    value2 : "value2"
}));

assertTrue("Multiple", clone(obj).merge(mergeObj, mergeObj2).equals({
    name : "track",
    value : "mergeObj2",
    value2 : "value2-mergeObj2",
    value3 : "value3"
}));

assertTrue("Multiple no Override", clone(obj).merge(mergeObj, mergeObj2, false).equals({
    name : "trick",
    value : "value",
    value2 : "value2",
    value3 : "value3"
}));

var deep = {
    first : {
        name : "trick",
        val : "value"
    },
    second : {
        foo : "bar"
    }
};

var deepMerge = {
    first : {
        name : "track",
        anotherVal : "wohoo"
    },
    second : {
        foo : "baz",
        bar : "bam"
    },
    v : "on first layer"
};

assertTrue("Deep merges", clone(deep).merge(deepMerge).equals({
    first : {
        name : "track",
        val : "value",
        anotherVal : "wohoo"
    },
    second : {
        foo : "baz",
        bar : "bam"
    },
    v : "on first layer"
}));

assertTrue("Deep merges no override", clone(deep).merge(deepMerge, false).equals({
    first : {
        name : "trick",
        val : "value",
        anotherVal : "wohoo"
    },
    second : {
        foo : "bar",
        bar : "bam"
    },
    v : "on first layer"
}));

var obj1 = {a: 1, b: "hello"};
obj1.merge({c: 3});
assertTrue(obj1.equals({a: 1, b: "hello", c: 3}));

obj1.merge({a: 2, b: "mom", d: "new property"}, false);
assertTrue(obj1.equals({a: 1, b: "hello", c: 3, d: "new property"}));

var obj2 = {};
obj2.merge({a: 1}, {b: 2}, {a: 3});
assertTrue(obj2.equals({a: 3, b: 2}));

var a = [];
var b = [1, [2, 3], 4];
a.merge(b);
assertEquals(1, a[0]);
assertEquals([2, 3], a[1]);
assertEquals(4, a[2]);


var o1 = {};
var o2 = {a: 1, b: {c: 2}};
var o3 = {d: 3};
o1.merge(o2, o3);
assertTrue(o1.equals({a: 1, b: {c: 2}, d: 3}));
o1.b.c = 99;
assertTrue(o2.equals({a: 1, b: {c: 2}}));

// checking types with arrays and objects
var bo;
a = [];
bo = [1, {0:2, 1:3}, 4];
b = [1, [2, 3], 4];

a.merge(b);
assertTrue("Array stays Array?", Array.isArray(a[1]));

a = [];
a.merge(bo);
assertTrue("Object stays Object?", !Array.isArray(a[1]));

a = [];
a.merge(b);
a.merge(bo);
assertTrue("Object overrides Array", !Array.isArray(a[1]));

a = [];
a.merge(b);
a.merge(bo, false);
assertTrue("Object does not override Array", Array.isArray(a[1]));

a = [];
a.merge(bo);
a.merge(b);
assertTrue("Array overrides Object", Array.isArray(a[1]));

a = [];
a.merge(bo);
a.merge(b, false);
assertTrue("Array does not override Object", !Array.isArray(a[1]));

내 평등 방법은 여기에서 찾을 수 있습니다. JavaScript의 객체 비교

~ 안에 mootools, 거기 있습니다 Object.Merge ():

Object.merge(obj1, obj2);

객체를 병합하는 것은 간단합니다.

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog', car: 'BMW' }
var obj3 = {a: "A"}


var mergedObj = Object.assign(obj1,obj2,obj3)

console.log(mergedObj);

객체는 오른쪽에서 왼쪽으로 병합되므로 오른쪽의 객체와 동일한 속성을 갖는 객체가 재정의됩니다.

이 예에서 obj2.car 재정의 obj1.car

~ 안에 Ext JS 4 다음과 같이 수행 할 수 있습니다.

var mergedObject = Ext.Object.merge(object1, object2)

// Or shorter:
var mergedObject2 = Ext.merge(object1, object2)

보다 병합 (Object) : 객체.

기반 마르 쿠스 ' 그리고 vsync '답변, 이것은 확장 된 버전입니다. 함수는 여러 가지 인수를 취합니다. 속성을 설정하는 데 사용할 수 있습니다 노드와 깊은 값 사본을 만듭니다. 그러나 첫 번째 주장은 참조로 제공됩니다.

dom 노드를 감지하려면 isdomnode () 함수가 사용됩니다 (스택 오버플로 질문 참조 JavaScript는 isdom - JavaScript 객체가 dom 객체인지 어떻게 확인합니까?)

테스트되었습니다 오페라 11, Firefox 6, 인터넷 익스플로러 8 및 Google 크롬 16.

암호

function mergeRecursive() {

  // _mergeRecursive does the actual job with two arguments.
  var _mergeRecursive = function (dst, src) {
    if (isDOMNode(src) || typeof src !== 'object' || src === null) {
      return dst;
    }

    for (var p in src) {
      if (!src.hasOwnProperty(p))
        continue;
      if (src[p] === undefined)
        continue;
      if ( typeof src[p] !== 'object' || src[p] === null) {
        dst[p] = src[p];
      } else if (typeof dst[p]!=='object' || dst[p] === null) {
        dst[p] = _mergeRecursive(src[p].constructor===Array ? [] : {}, src[p]);
      } else {
        _mergeRecursive(dst[p], src[p]);
      }
    }
    return dst;
  }

  // Loop through arguments and merge them into the first argument.
  var out = arguments[0];
  if (typeof out !== 'object' || out === null)
    return out;
  for (var i = 1, il = arguments.length; i < il; i++) {
    _mergeRecursive(out, arguments[i]);
  }
  return out;
}

몇 가지 예

HTML 요소의 내부 HTML 및 스타일을 설정합니다

mergeRecursive(
  document.getElementById('mydiv'),
  {style: {border: '5px solid green', color: 'red'}},
  {innerHTML: 'Hello world!'});

어레이 및 객체를 병합합니다. undefined는 lefthand 어레이/객체에서 값을 보존하는 데 사용될 수 있습니다.

o = mergeRecursive({a:'a'}, [1,2,3], [undefined, null, [30,31]], {a:undefined, b:'b'});
// o = {0:1, 1:null, 2:[30,31], a:'a', b:'b'}

JavaScript 객체 (NULL 포함)를 꿀벌하지 않는 주장은 무시됩니다. 첫 번째 인수를 제외하고 DOM 노드도 폐기됩니다. 새 String ()처럼 생성 된 IE Strings는 실제로 객체라는 것을주의하십시오.

o = mergeRecursive({a:'a'}, 1, true, null, undefined, [1,2,3], 'bc', new String('de'));
// o = {0:'d', 1:'e', 2:3, a:'a'}

두 객체를 새로운 (두 개 중 어느 것도 영향을 미치지 않고) 공급 {}에 연결하려면 첫 번째 인수로

var a={}, b={b:'abc'}, c={c:'cde'}, o;
o = mergeRecursive(a, b, c);
// o===a is true, o===b is false, o===c is false

편집하다 (Reaperoon) :

배열을 병합합니다

function mergeRecursive(obj1, obj2) {
  if (Array.isArray(obj2)) { return obj1.concat(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 if (Array.isArray(obj2[p])) {
        obj1[p] = obj1[p].concat(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;
}

와우 .. 이것은 여러 페이지에서 본 첫 번째 stackoverflow 게시물입니다. 다른 "답변"을 추가 한 것에 대한 사과

이 방법은 용입니다 ES5 & 이전 - ES6을 다루는 다른 답변이 많이 있습니다.

나는 아무것도 보지 못했습니다 "깊은" 객체 병합을 사용합니다 arguments 재산. 여기 내 대답이 있습니다. 콤팩트 & 재귀, 무제한 객체 인수를 통과 할 수 있습니다.

function extend() {
    for (var o = {}, i = 0; i < arguments.length; i++) {
        // if (arguments[i].constructor !== Object) continue;
        for (var k in arguments[i]) {
            if (arguments[i].hasOwnProperty(k)) {
                o[k] = arguments[i][k].constructor === Object ? extend(o[k] || {}, arguments[i][k]) : arguments[i][k];
            }
        }
    }
    return o;
}

댓글을 달린 부분은 선택 사항입니다. 단순히 객체가 아닌 인수 (오류 방지)가 통과 된 인수를 건너 뛸 것입니다.

예시:

extend({
    api: 1,
    params: {
        query: 'hello'
    }
}, {
    params: {
        query: 'there'
    }
});

// outputs {api: 1, params: {query: 'there'}}

이 대답은 지금이지만 바다에서 떨어졌습니다 ...

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

// result
result: {food: "pizza", car: "ford", animal: "dog"}

jQuery.extend () 사용 - 링크

// Merge obj1 & obj2 to result
var result1 = $.extend( {}, obj1, obj2 );

사용 _.merge () - 링크

// Merge obj1 & obj2 to result
var result2 = _.merge( {}, obj1, obj2 );

사용 _.extend () - 링크

// Merge obj1 & obj2 to result
var result3 = _.extend( {}, obj1, obj2 );

Object.Assign () ecmascript 2015 (ES6) - 링크

// Merge obj1 & obj2 to result
var result4 = Object.assign( {}, obj1, obj2 );

모두의 출력

obj1: { animal: 'dog' }
obj2: { food: 'pizza', car: 'ford' }
result1: {food: "pizza", car: "ford", animal: "dog"}
result2: {food: "pizza", car: "ford", animal: "dog"}
result3: {food: "pizza", car: "ford", animal: "dog"}
result4: {food: "pizza", car: "ford", animal: "dog"}

Lodash를 사용해야합니다 기본 거리

_.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
// → { 'user': { 'name': 'barney', 'age': 36 } }

와 함께 aUNDSCORE.JS, 객체 배열을 병합하려면 :

var arrayOfObjects = [ {a:1}, {b:2, c:3}, {d:4} ];
_(arrayOfObjects).reduce(function(memo, o) { return _(memo).extend(o); });

결과는 다음과 같습니다.

Object {a: 1, b: 2, c: 3, d: 4}

이 버전을 언급 할 가치가 있습니다 140BYT.ES 컬렉션 최소 공간 내에서 작업을 해결하고 있으며이 목적을 위해 시도해 볼 가치가 있습니다.

암호:

function m(a,b,c){for(c in b)b.hasOwnProperty(c)&&((typeof a[c])[0]=='o'?m(a[c],b[c]):a[c]=b[c])}

귀하의 목적을위한 사용 :

m(obj1,obj2);

여기에 있습니다 독창적 인 요점.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top