TIL_얕은 복사, 깊은 복사

박성훈·2022년 7월 20일

JavaScript

목록 보기
16/25
post-thumbnail

shallow copy(얕은 복사)

const obj = {
	name : 'kim',
    age : 27,
    company : {
    	name : 'codestates',
        id : 00001,
        department : dev
    }
}

const copiedObj = Object.assign({}, obj);

assign메소드로 객체를 복사했을 경우, 객체는 참조형 데이터이기 때문에 주소값을 복사하고, 그렇기때문에 복사본을 수정했을 경우 원본도 수정이 될 것 같지만,

위의 경우 shallow copy가 된 상황이다.

shallow copy : 객체를 트리구조로 봤을 때, 최상위 노드만 주소값으로 복사

이 때, 최상위 노드란 참조형 데이터를 말한다.

즉, obj객체의 지역변수인 name과 age는 값을 복사한 것이므로, 서로 영향을 받지 않지만, 객체인 company의 경우에는 주소값이 복사되므로, 서로 영향을 받게 된다.

Deep copy(깊은 복사)

위에서 본 얕은 복사의 경우 다르게 표현한다면 트리구조로 봤을 때,

위의 그림의 Depth 1 부분까지는 값이 복사되지만, Depth 2 부분 부터는 주소값이 복사되고 있다.
깊은 복사는 이러한 Depth 2 이상의 속성에 대해서 주소값이 아닌 값을 복사해주는 것을 말한다.

깊은 복사의 방법은 다음과 같다.

재귀함수를 통한 복사

객체 내의 value가 객체라면 그 객체에 대해 다시 처리를 해주는 방식이다.

const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

function copyObj(obj) { // 객체를 파라미터로 받아온다.
  const result = {};

  for (let key in obj) { // 객체의 키 값을 돌면서
    if (typeof obj[key] === 'object') { // 키의 value의 타입이 객체라면
      result[key] = copyObj(obj[key]); // 다시 그 value에 있는 객체를 파라미터로 받아 함수실행
    } else {
      result[key] = obj[key]; // 객체가 아니라면 값 할당 (값 복사)
    }
  }

  return result;
}

위 함수가 돌고 나면, 얕은 복사가 될 수 있는 b의 객체도 다시 함수의 파라미터로 들어가 result 객체에 할당되기 때문에, 주소값이 아닌 값이 복사될 수 있다.

JSON.stringify()

여기서는 JSON에 대해 제대로 학습하지 않았기 때문에, 간략하게 메소드 사용방법에 대해서만 기술하겠다.
(추후, JSON에 대한 콘텐츠에서 다시 다룰 예정)

JSON.stringify()를 사용하게 되면, 객체를 json문자열로 변환 후, JSON.parse()를 이용해 다시 자바스크립트의 객체로 만들어주면 깊은 복사가 이루어진다.

const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = JSON.parse(JSON.stringify(obj)); // 위 과정을 통해 원본객체와 참조가 끊기게 된다.

lodash 라이브러리

lodash라는 라이브러리를 사용하면 더 쉽게 깊은 복사를 수행할 수 있다.
lodash는 개발을 할 때 많이 사용하는 기능에 대한 유틸 함수들을 모아서 제공해주는 라이브러리이다.
npm을 통해 라이브러리 설치가 가능하고 _.함수명() 형태로 함수사용이 가능하다.

_.cloneDeep()함수를 통해 깊은 복사를 수행할 수 있다.

const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = _.cloneDeep(obj);

참조

https://velog.io/@th0566/Javascript-얕은-복사-깊은-복사

profile
프론트엔드 학습일지

0개의 댓글