Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript에서 두 개의 객체를 기반으로 새로운 객체 생성하기

JavaScript 개발을 하다 보면 서로 다른 두 객체의 속성을 하나로 합쳐 새로운 객체를 만들어야 하는 경우가 자주 있습니다. 이번 글에서는 두 객체를 병합하면서도 원본 객체는 그대로 유지하는 방법을 알아보겠습니다.

문제 상황

다음과 같이 두 개의 객체가 정의되어 있다고 가정해 보겠습니다.

const a = {
    a: 1,
    af: function() { console.log(this.a) },
};
const b = {
    b: 2,
    bf: function() { console.log(this.b) },
};

여기서 우리가 작성해야 할 함수는 이 두 객체를 인자로 받아, 각 객체가 가진 모든 속성을 포함하는 새로운 객체를 반환하는 것입니다. 결과물은 아래와 같은 형태가 됩니다.

const output = {
    a: 1,
    af: function() { console.log(this.a) },
    b: 2,
    bf: function() { console.log(this.b) },
}

중요한 점은 병합 과정에서 원본 객체인 ab는 변경되지 않고 그대로 유지되어야 한다는 것입니다.

extend 함수 구현

이 문제는 여러 개의 객체를 순회하며 속성을 하나씩 복사하는 방식으로 해결할 수 있습니다. 아래 코드는 가변 인자(arguments)를 활용해 두 개 이상의 객체도 처리할 수 있도록 작성된 extend 함수입니다.

const a = {
    a: 1,
    af: function() { console.log(this.a) },
};
const b = {
    b: 2,
    bf: function() { console.log(this.b) },
};
const extend = function(){
    let i, j, res = (arguments[0] || {});
    for (i = 1; i < arguments.length; i++) {
        const x = arguments[i];
        for (j in x) {
            if (x.hasOwnProperty(j)) {
                res[j] = x[j];
            }
        }
    }
    return res;
};
const c = extend({}, a, b);
console.log(c);

동작 방식 살펴보기

  • 첫 번째 인자인 빈 객체 {}를 병합 결과를 담을 대상으로 사용합니다.
  • 나머지 인자들을 순차적으로 순회하며 각 객체의 고유 속성(hasOwnProperty로 판별)만 대상 객체에 복사합니다.
  • 빈 객체에 복사하기 때문에 원본 객체 ab는 전혀 영향을 받지 않습니다.

실행 결과

위 코드를 실행하면 콘솔에 다음과 같은 출력이 나타납니다.

{ a: 1, af: [Function: af], b: 2, bf: [Function: bf] }

더 간단한 현대적인 방법

참고로 최신 JavaScript(ES6 이상)에서는 위와 같은 함수를 직접 작성하지 않고도 훨씬 간결하게 같은 결과를 얻을 수 있습니다.

Object.assign 사용

const c = Object.assign({}, a, b);

스프레드(Spread) 연산자 사용

const c = { ...a, ...b };

두 방법 모두 첫 번째 위치의 빈 객체(또는 새 리터럴)에 원본 객체들의 속성을 복사하므로, 원본 객체는 변경되지 않습니다. 실무에서는 코드의 가독성과 유지보수성을 위해 Object.assign이나 스프레드 연산자를 사용하는 것이 권장됩니다.