etc./StackOverFlow

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

청렴결백한 만능 재주꾼 2021. 11. 11. 07:58
반응형

질문자 :Community Wiki


런타임에 두 개의 (매우 간단한) 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};

merged 은 이제 obj1obj2 의 합집합입니다. 의 속성 obj2 에서 그 덮어 쓰게됩니다 obj1 .

 /** 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-transform-object-rest-spread 플러그인이 필요합니다.

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 자바스크립트 참조 참조 )


ES5 및 이전 버전을 위한 방법

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

이 단지의 모든 속성 추가 않습니다 obj2obj1 여전히 수정되지 않은 사용하려는 경우 당신이 원하는 것을하지 않을 수있는 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; }

Community Wiki

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.

Community Wiki

Harmony ECMAScript 2015(ES6) 는 이를 수행할 Object.assign 을 지정합니다.

 Object.assign(obj1, obj2);

현재 브라우저 지원이 개선 되고 있지만 지원하지 않는 브라우저용으로 개발 중인 경우 polyfill 을 사용할 수 있습니다.


Community Wiki

개체 속성을 병합하는 코드를 검색하여 여기까지 왔습니다. 그러나 재귀 병합을 위한 코드가 없었기 때문에 직접 작성했습니다. (어쩌면 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 } } };

Community Wiki

underscore.jsextend -method는 한 줄짜리로 이 작업을 수행합니다.

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

Community Wiki

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

Community Wiki

오늘은 개체를 병합해야 하는데 이 질문(및 답변)이 많은 도움이 되었습니다. 나는 몇 가지 답변을 시도했지만 그 중 어느 것도 내 요구에 맞지 않았기 때문에 몇 가지 답변을 결합하고 직접 추가하고 새로운 병합 기능을 생각해 냈습니다. 여기있어:

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

Community Wiki

이를 위해 객체 확산 구문 을 사용할 수 있습니다. ES2018 및 그 이후 버전의 일부입니다.

 const obj1 = { food: 'pizza', car: 'ford' }; const obj2 = { animal: 'dog' }; const obj3 = { ...obj1, ...obj2 }; console.log(obj3);


Community Wiki

한 줄의 코드로 N개 개체의 속성 병합

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

Community Wiki

for..in 루프에서 source.hasOwnProperty(property) 를 확인하도록 수정되어야 합니다. 그렇지 않으면 거의 원하지 않는 전체 프로토타입 체인의 속성을 복사하게 됩니다...


Community Wiki

다음 두 가지가 좋은 출발점이 될 것입니다. lodash에는 이러한 특별한 요구 사항을 위한 커스터마이저 기능도 있습니다!

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


Community Wiki

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

이것이 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);

Community Wiki

여기 내 찌르기가 있습니다.

  1. 깊은 병합 지원
  2. 인수를 변경하지 않음
  3. 임의의 수의 인수를 취합니다.
  4. 개체 프로토타입을 확장하지 않습니다.
  5. 다른 라이브러리( jQuery , MooTools , Underscore.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 }; */

Community Wiki

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.

Community Wiki

너무 복잡하지 않은 객체의 경우 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_/

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


Community Wiki

GitHub에 deepmerge 라는 라이브러리가 있습니다. npm 및 bower 패키지 관리자를 통해 사용할 수 있는 독립 실행형입니다.

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


Community Wiki

이를 수행하는 가장 좋은 방법은 Object.defineProperty를 사용하여 열거할 수 없는 적절한 속성을 추가하는 것입니다.

이렇게 하면 Object.prototype.extend를 사용하여 속성을 생성할 경우 얻을 수 있는 새로 생성된 "확장" 없이 개체 속성을 계속 반복할 수 있습니다.

이것이 도움이 되기를 바랍니다.

Object.defineProperty(Object.prototype, "확장", {
    열거 가능: 거짓,
    값: 함수(에서) {
        var 소품 = Object.getOwnPropertyNames(from);
        var 대상 = 이것;
        props.forEach(함수(이름) {
            if (목적지의 이름) {
                var 대상 = Object.getOwnPropertyDescriptor(from, name);
                Object.defineProperty(목적지, 이름, 목적지);
            }
        });
        이것을 반환하십시오;
    }
});

작업이 완료되면 다음을 수행할 수 있습니다.

var obj = {
    이름: '스택',
    마침: '오버플로'
}
var 대체 = {
    이름: '주식'
};

obj.extend(교체);

방금 여기에 대한 블로그 게시물을 작성했습니다. http://onemoredigit.com/post/1527191998/extending-objects-in-node-js


Community Wiki

extend 사용할 수 있습니다.

 var obj1 = { val1: false, limit: 5, name: "foo" }; var obj2 = { val2: true, name: "bar" }; jQuery.extend(obj1, obj2);

이제 obj1 obj1obj2 의 모든 값이 포함됩니다.


Community Wiki

프로토타입 에는 다음이 있습니다.

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

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


Community Wiki

**객체 병합은 Object.assign 또는 Spread ... 연산자를 사용하여 간단합니다. **

 var obj1 = { food: 'pizza', car: 'ford' } var obj2 = { animal: 'dog', car: 'BMW' } var obj3 = {a: "A"} var mergedObj = Object.assign(obj1,obj2,obj3) // or using the Spread operator (...) var mergedObj = {...obj1,...obj2,...obj3} console.log(mergedObj);

개체는 오른쪽에서 왼쪽으로 병합됩니다. 즉, 오른쪽에 있는 개체와 동일한 속성을 가진 개체가 재정의됩니다.

이 예에서 obj2.carobj1.car


Community Wiki

누군가 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'

Community Wiki

와우.. 이것은 내가 여러 페이지에서 본 최초의 StackOverflow 게시물입니다. 다른 "답변"을 추가한 것에 대해 사과드립니다.


ES5 및 이전 버전

이 방법은 ES5 및 이전 버전을 위한 것입니다. ES6을 다루는 다른 답변이 많이 있습니다.

arguments 속성을 사용하여 병합되는 "깊은" 개체를 보지 못했습니다. 내 대답은 다음과 같습니다. compact & recursive 무제한 객체 인수를 전달할 수 있습니다.

 function extend() { for (var o = {}, i = 0; i < arguments.length; i++) { // Uncomment to skip arguments that are not objects (to prevent errors) // 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 objects */ function extend() { for (var o = {}, i = 0; i < arguments.length; i++) { 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; } /** * Example */ document.write(JSON.stringify(extend({ api: 1, params: { query: 'hello' } }, { params: { query: 'there' } }))); // outputs {"api": 1, "params": {"query": "there"}}


이 대답은 이제 바다의 한 방울에 불과합니다 ...





Community Wiki

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

  • 여러 개체를 병합할 수 있는 가능성을 추가했습니다.
  • 깊은 물체 지원
  • 재정의 매개변수(마지막 매개변수가 부울인 경우 감지됨)

override가 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.bc = 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]));

내 equals 메서드는 여기에서 찾을 수 있습니다. JavaScript의 객체 비교


Community Wiki

MooTools 에는 Object.merge()가 있습니다 .

 Object.merge(obj1, obj2);

Community Wiki

Ext JS 4에서는 다음과 같이 할 수 있습니다.

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

merge( object ) : Object 를 참조하십시오.


Community Wiki

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"}

Community Wiki

Markus'vsync' 답변을 기반으로 하는 확장된 버전입니다. 함수는 임의의 수의 인수를 취합니다. DOM 노드의 속성을 설정하고 값의 전체 복사본을 만드는 데 사용할 수 있습니다. 그러나 첫 번째 인수는 참조로 제공됩니다.

DOM 노드를 감지하기 위해 isDOMNode() 함수가 사용됩니다(스택 오버플로 질문 JavaScript isDOM — JavaScript 개체가 DOM 개체인지 확인하는 방법 참조).

Opera 11, Firefox 6, Internet Explorer 8 및 Google Chrome 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 요소의 innerHTML 및 스타일 설정

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

배열과 개체를 병합합니다. undefined는 왼쪽 배열/객체의 값을 보존하는 데 사용할 수 있습니다.

 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 노드도 버려집니다. 즉, new String()처럼 생성된 문자열은 사실 객체라는 점에 주의하십시오.

 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

편집 (ReaperSoon 작성):

또한 배열을 병합하려면

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

Community Wiki

lodash의 defaultsDeep을 사용해야 합니다.

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

Community Wiki

Underscore.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}

Community Wiki

 let obj1 = {a:1, b:2}; let obj2 = {c:3, d:4}; let merged = {...obj1, ...obj2}; console.log(merged);


Community Wiki

출처 : http:www.stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically

반응형