[Javascript] 객체 병합

motiveko·2021년 12월 13일
0
post-thumbnail

자바스크립트 프로그래밍을 하다 보면 여러 객체를 합쳐야 하는 경우가 많이 발생한다. 이 때 여러가지 방법이 있는데 하나씩 알아보자.

1. 스프레드 문법 사용

객체에 스프레드 프로퍼티 문법(...)을 사용해서 합치려는 객체를 각각 펼친 후 하나의 객체로 만들 수 있다.

const obj1 = { key1: 'val1' };
const obj2 = { key2: 'val2' };
const merged = { ...obj1, ...obj2 }; // { key1: 'val1', key2: 'val2' }

2. Object.assign()메서드 사용

스프레드 프로터피 문법과 함께 TC39 stage4에 제안된 Object.prototype.assign을 사용해서 객체를 복사할 수 있다. 형식은 아래와 같고, source를 target에 복사해서 반환하는 형태다.

assign(target: object, ...sources: any[]): any;
const obj1 = { key1: 'val1' };
const obj2 = { key2: 'val2' };
const merged = Object.assign({}, obj1, obj2); // { key1: 'val1', key2: 'val2' }

Object.assign()함수는 새로운 객체를 반환하는게 아닌 target 객체를 변경시키는 방식으로 작동하므로 주의가 필요하다. immutable하게 사용해야 하면 위에처럼 target에 빈 객체 리터럴을 넣어주는 방식으로 사용할 수 있다.


두가지 방법 모두 한계가 있는데, 중첩 객체를 병합할 때가 그렇다.

const obj1 = {
    key1: 'val1',
    key2: {
        a: 'A'
    }
}
const obj2 = {
    key1: 'val2',
    key2: {
        b: 'B'
    }
}

const merged1 = {...obj1, ...obj2}; 
const merged2 = Object.assign({}, obj1, obj2);
// 둘 모두 { key1: 'val2', key2: { b: 'B' }}

두가지 문법 모두key2의 값은 뒷쪽에 사용된 객체의 값으로 덮어썼다. 하지만 { a: 'A', b: 'B' }로 만들어야 하는 경우는 생긴다.

3. lodash.merge()

직접 객체를 병합하는 반복문같은걸 만들수 있겠지만 번거로운 일이다. lodashmerge를 사용하면 간단하게 해결할 수 있다.

interface LoDashStatic {
  // ...
  merge(object: any, ...otherArgs: any[]): any;
  // ...
}
import * as _ from 'lodash';
describe('test', () => {
 
  fit('객체 병합 테스트', () => {
    const obj1 = {
      key1: 'val1',
      key2: {
        a: 'A'
      }
    };
    const obj2 = {
      key1: 'val2',
      key2: {
        b: 'B'
      }
    };
    const merged = _.merge({}, obj1, obj2); 
    expect(merged).toEqual({ key1: 'val2', key2: { a:'A', b: 'B' }}); // true
  });
});

lodashmergeObject.assign와 비슷하게 작동한다. 첫째 인자로 받은 targe 객체에 뒤의 source 객체들을 깊은 merge 한 후 targe 객체를 반환한다. 따라서 새로운 객체를 생성하진 않으므로 immutable하게 하려면 위의 방식처럼 빈 객체 리터럴을 target에 넣어주면 될 것 같다.

lodash의 다른 기능도 파보면 유용할 것 같다.

0개의 댓글