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

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


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


답변

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.


답변

하모니는 2015 년 (ES6) ECMA 스크립트 지정 Object.assign이 작업을 수행 할 것입니다.

Object.assign(obj1, obj2);

현재 브라우저 지원이 향상 되고 있지만 지원되지 않는 브라우저를 개발하는 경우 polyfill을 사용할 수 있습니다 .


답변

객체 속성을 병합하는 코드를 검색하여 여기에 올렸습니다. 그러나 재귀 병합을위한 코드가 없기 때문에 직접 작성했습니다. (아마도 jQuery extend는 재귀 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.jsextend-method이 한 라이너에서이 작업을 수행합니다 :

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