나만보는개발공부블로그

Shallow Copy & deep Copy 본문

Javascript&Typescript

Shallow Copy & deep Copy

alexrider94 2021. 3. 23. 21:41

변수를 복사하다보면 바라보는 객체도 동일하게 되고 두개의 변수 중 하나만 변경되어도 나머지 하나도 동일하게 수정되는 현상이 발생한다.

-자바스크립트에서는 기본 자료형(숫자,문자열,boolean)의 값을 복사할 때 값을 완전히 복사한다.

let s = "test";
let t = s;
s = "hi";
console.log(t);

위의 경우 t에 s의 값을 복사해주고 s의 값을 변경했지만 t의 변화는 없는데 t에 값만 복사 한 경우이다.

let s = ['a','b','c'];
let t = s;
t[0]='d';
console.log(s);

객체의 경우에는 s의 첫 인덱스를 변경했더니 같이 변경되는 현상이 발생한다. 이것이 객체의 특징인데 객체는 다른 변수에 대입할때 값을 복사하는 게 아니라 참조인 메모리의 주소를 복사한다.

 

let s = ['a','b','c'];
let t = Array.prototype.slice.call(s);
t[0]='d';
console.log(s);

위의 경우를 막기 위해서는 call 함수를 통해서 막을 수 있다. copy라고 부르며 이제는 값이 변해도 s에 영향을 미치지않게 되었다.  copy에는 두가지가 있는데 얕은 복사(=Shallow Copy)와 깊은 복사(=Deep Copy)가 있다. 

 

Shallow Copy

-가장 상위 객체만 새로 생성되고 내부 객체들은 참조 관계인 경우를 의미

 

let test = [{id:'A101'},{id:'B101'}];
let shallow = Array.prototype.slice.call(test);
shallow[0].id = 'A102';
shallow[1] = 'B102';
console.log(test);

위의 경우에는 shallow[0].id는 test에 적용되지만 shallow[1]은 적용되지 않는데 얕은 복사의 예시이다. 가장 상위 객체에 직접 변경하는것은 적용되지 않지만 내부 객체들은 참조로 이루어져있어 적용되어서이다.

Deep Copy 

- 내부 객체까지 모두 새로 생성된 것을 의미

 

function deepClone(obj, hash = new WeakMap()) {
    if (Object(obj) !== obj) return obj; // primitives
    if (hash.has(obj)) return hash.get(obj); // cyclic reference
    const result = obj instanceof Set ? new Set(obj) // See note about this!
                 : obj instanceof Map ? new Map(Array.from(obj, ([key, val]) =>
                                        [key, deepClone(val, hash)]))
                 : obj instanceof Date ? new Date(obj)
                 : obj instanceof RegExp ? new RegExp(obj.source, obj.flags)
                 // ... add here any specific treatment for other classes ...
                 // and finally a catch-all:
                 : obj.constructor ? new obj.constructor()
                 : Object.create(null);
    hash.set(obj, result);
    return Object.assign(result, ...Object.keys(obj).map(
        key => ({ [key]: deepClone(obj[key], hash) }) ));
}

let p = {
  data: 1,
  children: [{
    data: 2,
    parent: null
  }]
};
let q = deepClone(p);
q.children[0].data = 3;
console.log(p.children[0].data);

위의 deepClone함수가 deepCopy를 해주는 함수이다.  아래에서 p의 값을 변경해도 q는 변경되지 않는것을 확인할 수 있다.

'Javascript&Typescript' 카테고리의 다른 글

함수형 컴포넌트의 제너릭 타입 설정.  (0) 2021.12.04
Splice()  (0) 2021.06.17
Hoisting  (0) 2021.03.04
Iterable & Iterator  (0) 2021.02.23
FP & OOP  (0) 2021.02.22