소근소근

[Javascript] object reference , shallow / deep cloning 객체 참조 복사 / 값 복사 본문

HTML,CSS,Javascript

[Javascript] object reference , shallow / deep cloning 객체 참조 복사 / 값 복사

JJureng 2021. 9. 7. 20:46
728x90
반응형
SMALL

자바스크립트에서 = 로 객체를 복사하려고 하면 복사가 되지 않고 '참조' 를 하게 된다.

 

즉 값을 복사하는 것이 아니라 원래 객체의 주소값을 가리키게 된다. 

 

 

객체의 참조 복사(shallow cloning)


let obj = {
    a : 'a',
    b : 'b',
    c : 'c'
};

let notclone = obj;
obj.c = 'changed';

console.log(obj);
console.log(notclone);

콘솔 출력

> {a: 'a', b: 'b', c: 'changed'}
> {a: 'a', b: 'b', c: 'changed'}

 

notclone = obj 으로 notclone은 obj의 주소값을 가리키게 된다. 

그렇기 때문에 obj의 내용을 바꾸면 notclone에도 반영이 된다. 

 

객체의 값 복사 (deep cloning)


let obj = {
    a : 'a',
    b : 'b',
    c : 'c'
};

let notclone = obj;
let clone = Object.assign({} , obj); //deep
let clone2 = {...obj}; //deep

obj.c = 'changed';

console.log(obj);
console.log(notclone);
console.log(clone);
console.log(clone2);

콘솔 출력

> {a: 'a', b: 'b', c: 'changed'}
> {a: 'a', b: 'b', c: 'changed'}
> {a: 'a', b: 'b', c: 'c'}
> {a: 'a', b: 'b', c: 'c'}

 

clone , clone2  객체는 참조가 아니라 obj의 값을 복사하여 독립성을 가지는 것을 볼 수 있다. 

obj의 값을 바꾸어도 이 두 객체에는 영향을 주지 않는다. 

 


만약  이렇게 객체 속에 객체가 있는 경우라면

let obj = {
    a : 'a',
    b : 'b',
    c : {
        inner : 'copy?'
    }
};

let notclone = obj;
let clone = Object.assign({} , obj); 
let clone2 = {...obj}; 

obj.c.inner = 'changed';

console.log(obj);
console.log(notclone);
console.log(clone);
console.log(clone2);

내부 객체는 복사가 아니라 참조가 되기 때문에 obj의 값을 바꾸면 나머지 객체 모두에게 반영이 된다.

내부 객체까지 복사를 하기 위해서는 

 

let innerclone = JSON.parse(JSON.stringify(obj));

이렇게 해주면 된다. 

 

유의할 점은, 객체를 stringify했다가 다시 parsing하기 때문에 크기가 커질수록 속도가 느려지는 것이다.

 

728x90
반응형
LIST