기술 블로그

[TIL] 깊은 복사 본문

프론트엔드/Javascript

[TIL] 깊은 복사

jaegwan 2023. 10. 23. 21:38
반응형

자바스크립트에서 객체의 최상단 레벨만 값으로서 복사되는 것을 얕은 복사라고 하고

모든 레벨에서 값으로서 복사되는 것을 깊은 복사라고 한다.

깊은 복사를 위한 방법으로는 다음과 같은 방법이 있다.

  1. JSON.stringyfy

JSON.stringify()와 JSON.parse()를 이용한 깊은 복사(deep copy) 방법은 JavaScript 객체를 복사할 때 사용할 수 있는 간단한 방법 중 하나이다. 이 방법은 객체의 모든 내용을 문자열로 변환한 다음, 그 문자열을 다시 객체로 파싱하여 복사본을 생성하는 방법이다.

단점

  • 경우에 따라 다를 수 있으나 크기가 클 경우 성능 문제가 있다.
  • 함수와 메서드는 문자열로 변환되지 않기 때문에 복사된 문자열에는 포함되어있지않다.
  • 객체가 순환참조를 가지고 있다면 에러가 나타난다.
  • 특수한 객체(Date나 정규식)은 제대로 복사가 안될 수 있다.
  • 프로토타입 체인을 고려하지 않는다.
  1. 외부 라이브러리 사용
  • immer
  • lodash
  1. 직접 재귀함수로 구현

객체와 원시값 복사가 이뤄지는 재귀함수

function deep(obj) {
    const obj2 = {};
    for (let i in obj) {
        if (typeof obj[i] !== 'object') {
            // i is imutable
            obj2[i] = obj[i];
        } else {
            obj2[i] = deep(obj[i]);
        }
    }
    return obj2;
}

null처리, 순환참조, 기타 자료형의 처리가 이뤄지는 재귀함수

function deepCopy(obj, hash = new WeakMap()) {
    if (hash.has(obj)) return hash.get(obj); // 순환 참조 처리

    if (obj === null) return null; // null 처리
    if (typeof obj !== 'object') return obj; // 원시 타입 처리

    if (Array.isArray(obj)) { // 배열 처리
        const copy = [];
        hash.set(obj, copy);
        for (const item of obj) {
            copy.push(deepCopy(item, hash));
        }
        return copy;
    }

    // 일반 객체 처리
    const copy = {};
    hash.set(obj, copy);
    for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
            copy[key] = deepCopy(obj[key], hash);
        }
    }
    return copy;
}
반응형

'프론트엔드 > Javascript' 카테고리의 다른 글

[TIL] 객체에 정렬 곁들이기  (0) 2023.11.09
[TIL] 클로저  (0) 2023.11.06
[TIL]꼬리 재귀  (0) 2023.10.13
[TIL]동기와 비동기  (0) 2023.10.13
상속과 프로토타입  (0) 2023.08.07
Comments