javascript object merge

Object.assign

Javascript의 Object를 Merge 하는 방법 중에 가장 많이 사용되는 것은 Object.assign을 사용하는 것이다.

기본 사용법은 다음과 같다.

Object.assign(target, ...sources)

  • target : Merge 당할 대상 객체
  • source : Merge의 대상 객체에게 주입을 할 오브젝트
기본 사용법
var obj1 = {name : 'hi', val: 1};
var obj2 = {name : 'hello', val: 2};

var newObj = Object.assign(obj1, obj2);

console.log(obj1);
console.log(newObj);

obj1.name = 'modified';

console.log(obj1);

if (obj1 === newObj){
    console.log('same object!!')
}

실행 결과

{ name: 'hello', val: 2 }
{ name: 'hello', val: 2 }
{ name: 'modified', val: 2 }
same object!!

여기서 주목해야할 점은 target의 object는 assign 이후 자기 자신의 original 영역을 지속적으로 참조 하고 있다는 것이다.

  • 즉, obj1과 newobj는 완전히 동일한 object라는 것이다.

target이었던 obj1의 값은

var newObj = Object.assign(obj1, obj2);

이후 obj2의 값으로 덮어 쒸워 지는 것을 볼 수 있다.

  • target의 object는 source object와 동일한 properties가 있다면 overwrite 되게 된다.

코드를 아래와 같이 살짝 변경해 보겠다.

var obj1 = {pre:'King', name : 'hi', val: 1};
var obj2 = {name : 'hello', val: 2, nextVal :3};

var newObj = Object.assign(obj1, obj2);

console.log(obj1);
console.log(newObj);

obj1.name = 'modified';

console.log(obj1);

if (obj1 === newObj){
    console.log('same object!!')
}

변경 점은 source에 pre property가 생겼고, obj2에는 nextVal을 생성 했다. 해당 코드를 실행해 보면 아래와 같은 결과 값을 확인 할 수 있다.

{ pre: 'King', name: 'hello', val: 2, nextVal: 3 }
{ pre: 'King', name: 'hello', val: 2, nextVal: 3 }
{ pre: 'King', name: 'modified', val: 2, nextVal: 3 }
same object!!

상위 결과에서 볼 수 있듯이

  • 해당 메서드는 서로에게 갖지 않는 값에 대해서는 target으로 값이 주입된다.
Cloning

이러한 방법을 이용해서 객체에 대한 내부 properties Cloning이 가능하다.

var obj1 = {pre:'King', name : 'hi', val: 1};

var clonedObj = Object.assign({}, obj1);

console.log(obj1);
console.log(clonedObj);

obj1.name = 'modified';

console.log(obj1);

if (obj1 === clonedObj){
    console.log('same object!!');
} else {
    console.log('different object!!');
}

결과 값은 다음과 같다.

{ pre: 'King', name: 'hi', val: 1 }
{ pre: 'King', name: 'hi', val: 1 }
{ pre: 'King', name: 'modified', val: 1 }
different object!!

객체에 대한 정보를 동일하게 copy 하였으나,

  • 기존 object와는 다른 object를 생성한 것을 확인 가능하다.

ES6 Spread Operator

ES6 문법에서 사용되는 spread operator를 이용해서 merge가 가능하다.

기본 사용법
var obj1 = [1,2,3];
var obj2 = [4,5,6];

var length = obj1.push(...obj2);

console.log(length);
console.log(obj1);
obj1.push(7);
console.log(obj2);

if (obj1 === obj2){
    console.log('same object!!');
} else {
    console.log('different object!!');
}

결과값은 다음과 같다.

6
[ 1, 2, 3, 4, 5, 6 ]
[ 4, 5, 6 ]
different object!!

본 사용법은 사실 object간의 결합을 대상으로 하지 않는다. spread operator 자체가 array와 같은 Iterator성 객체를 대상으로한 문법이기 때문이다.

  • 결과적으로 Array의 결합으로 볼수 있으나 object의 merge용도로 사용되지는 않는다.

이런식의 코드도 많이 사용할 수 있다.

var obj1 = [1,2,3];
var obj2 = [...obj1, 4,5,6];

console.log(obj2); ```


```shell
[ 1, 2, 3, 4, 5, 6 ] ```

ECMAScript 2018 기준으로는 다음 코드도 사용이 가능하다.

var obj1 = {test:1};
var obj2 = {test:2,after:3};

var merged = {...obj1, ...obj2};
console.log(obj1); ```


그러나 아직 널리 사용 되지 않음으로 더 다루지 않는다.

Undersocre Extend

언더스코어 라이브러리를 사용해서 객체 머지가 가능하다.

기본 사용법
const _ = require('underscore');

var obj1 = {a:1,b:2};
var obj2 = {c:3,d:4};
var obj3 = {c:3,d:5,e:6};

_.extend(obj1, obj2, obj3);

console.log(obj1);

if (obj1 === obj2) {
    console.log('same Object');
} else {
    console.log('different Object');
}

결과는 다음과 같다.

{ a: 1, b: 2, c: 3, d: 5, e: 6 }
different Object

Object.assign과 같이 target만을 수정하고, 이후 들어오는 source 객체들은 변화가 없다.

lodash merge

로데쉬 라이브러리의 merge기능을 사용하는것도 가능하다.

기본 사용법
const _ = require('lodash');

var obj1 = {a:1,b:2};
var obj2 = {c:3,d:4};
var obj3 = {c:3,d:5,e:6};

var newObj = _.merge(obj1,obj2,obj3);

obj1.a = 3;

console.log(obj1);
console.log(newObj);

if (obj1 === newObj) {
    console.log('same Object');
} else {
    console.log('different Object');
}

결과값은 다음과 같다.

{ a: 3, b: 2, c: 3, d: 5, e: 6 }
{ a: 3, b: 2, c: 3, d: 5, e: 6 }
same Object
728x90
반응형

'Web' 카테고리의 다른 글

Web Components Callback Methods & lifecycle  (0) 2021.08.14
Web component (Custom Elements, Shadow DOM, Template)  (0) 2021.08.14
Gradle's dependency cache may be corrupt  (1) 2021.05.21
webpack basic with webstorm  (0) 2020.03.27
Vue basic with webstorm  (0) 2020.03.27