자바스크립트 객체의 깊은 복사

민겸·2023년 4월 5일
0

JavaScript

목록 보기
19/20

깊은 복사 방법 종류

자바스크립트의 객체를 깊은 복사하는 방법에는 여러 가지가 있다.

  • for문과 재귀함수의 조합
  • JSON 객체의 stringify(), parse() 메서드
  • structuredClone()
  • lodashcloneDeep()

순서대로 알아보도록 하자.


재귀 함수

for문을 돌려서 프로퍼티의 값이 Object라면 재귀적으로 함수를 호출하여 새로운 객체{}를 만들어서 키를 할당하는 방식이다.

장점

  • 아무런 라이브러리의 도움을 받지 않아도 된다.

단점

  • 코드가 길어지고 복잡해진다.

사용 예시

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

function deepCopyObj(original) {
  // 들어온 값이 null 또는 object 타입이 아니라면 그대로 반환
  if(original === null || typeof original !== 'object') return original;
  
  // 객체인지 배열인지 검사 후 객체라면 {}, 배열이라면 []
  const copied = Array.isArray(original) ? [] : {};

  for (let key in original) {
    copied[key] = deepCopyObj(original[key]);
  }

  return copied;
}

let copiedObj = deepCopyObj(objectWillCopied);

copiedObj.b.c = 3

console.log(objectWillCopied.b.c === copiedObj.b.c) //false

JSON.stringify(), JSON.parse()

내장 객체 JSON의 메서드를 사용한 깊은 복사 방법은 그다지 어렵지 않다.

  1. 복사하고 싶은 객체를 JSON.stringify()를 사용하여 객체문자열로 바꾼다.
    이렇게 메모리상에 존재하는 객체문자열로 변환하는 것을 직렬화(Serialization)라고 한다. 이 과정에서 원본 객체와의 참조가 모두 끊어진다.

  2. 직렬화된 문자열(객체였던 것)을 JSON.parse()를 사용하여 객체로 바꾼다.
    이렇게 다시 문자열객체로 변환하는 것을 역직렬화(Deserialization) 또는 파싱(parsing)이라고 한다.

장점

  • 메서드 두 개만 사용하면 간편하게 깊은 복사가 가능하다.

단점

  • 재귀 함수에 비해 느리다.
  • 복사하려는 객체의 크기가 일정 수준을 넘어가면, structuredClone보다 느리다.
  • 객체 내의 함수를 복사하려 할 경우, undefined를 반환한다.

사용 예시

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

const stringifiedObject = JSON.stringify(objectWillCopied); // 직렬화

const copiedObj = JSON.parse(stringifiedObject); // 역직렬화 또는 파싱

copiedObj.b.c = 3; 

console.log(objectWillCopied.b.c === copiedObj.b.c); // false

structuredClone()

structuredClone은 수많은 HTML DOM API중 하나로, structured clone 알고리즘을 이용하여 주어진 값의 깊은 복사본을 생성해주는 API이다.

장점

  • 코드의 길이가 가장 짧다.
  • JSON 객체의 메서드를 이용한 복사의 단점이 보완되는 부분이 존재한다.
    • RegExp, Blob, FileFileList, ImageData 객체들도 복사할 수 있다.

단점

  • DOM API라서 Node.js환경에서 작동하지 않는다.

사용 예시

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

const copiedObj = structuredClone(objectWillCopied);

copiedObj.b.c = 3; 

console.log(objectWillCopied.b.c === copiedObj.b.c); // false

lodash의 cloneDeep()

lodash는 객체나 배열 등의 자료 구조를 쉽게 변환하여 사용할 수 있게 도와주는 자바스크립트 라이브러리이다.

lodash의 설치는 홈페이지에서 참고할 수 있다.

lodash의 수많은 메서드들 중에 cloneDeep메서드는 객체의 깊은 복사를 수행하는 함수이다.

장점

  • 많은 검증을 받은 라이브러리로, 쉽고 안전하다.

단점

  • 별도의 설치가 필요하며, 설치 파일의 크기가 크다.

사용 예시

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

const copied = _.cloneDeep(objectWillCopied);

copied.b.c = 3;

console.log(copied.b.c === objectWillCopied.b.c); // false
profile
기술부채상환중...

0개의 댓글