본문 바로가기

자바스크립트

JavaScript에서 객체 복사에 JSON 을 사용하는 시대는 끝났다!

728x90

앞으로 깊은 복사 할 때는 structuredClone  을 사용합시다!

https://developer.mozilla.org/ja/docs/Web/API/structuredClone

 

structuredClone() - Web API | MDN

グローバルの structuredClone() メソッドは、指定された値のディープコピーを、構造化複製アルゴリズムを用いて生成します。

developer.mozilla.org

const obj = { hoge: [new Date(2023, 3, 12), 1], fuga: 'foo' };

const objClone = structuredClone(obj); // 깊은 복사

obj.hoge[1] = 10;
console.log(objClone.hoge[1]); // 1

objClone.hoge[0].setFullYear(2050);
console.log(obj.hoge[0].getFullYear()); // 2023

 

 

배경

자바스크립트의 객체와 배열의 대입은 얕은 복사입니다.

const arr = [0, 1, 2];
const arr2 = arr; // 얕은 복사

arr[0] = 10;
console.log(arr2[0]); // 10

arr2는 arr의 얕은 복사본이며 실제로는 같은 배열을 가리키기 때문에 arr에 대한 변경 사항은 arr2에서도 반영되어 보입니다.

 

위의 예제에서 arr2가 arr에 대한 변경 사항이 반영되지 않도록 깊은 복사 , 즉

const arr2 = arr.slice()

와 같은 방법을 사용할 수 있습니다.

그러나 그것은 위의 예제가 간단한 원시 값 배열이었기 때문입니다.

객체나 배열이 중첩된 값 전체를 깊은 복사하는 것은 어렵습니다.

 

const arr = [{ hoge: [0] }, { hoge: [1] }, { hoge: [2] }];
const arr2 = arr.map(x => ({ hoge: x.hoge.slice() })); // 깊은 복사

arr[0].hoge[0] = 10;
console.log(arr2[0].hoge[0]); // 0

무엇보다 위의 방법은 값의 구조에 따라 깊은 복사 코드를 변경해야한다는 문제가 있습니다.

그래서 평범한 객체, 배열 및 원시 값의 조합으로 이루어진 값을 깊은 복사하는 일반적인 방법으로는 JSON화하는 방법이 있습니다.

 

JSON.parse(JSON.stringify)

전체 객체나 배열을 복제하기 위해서는 먼저 JSON 화를 수행하는 것이 일반적이었습니다.

const objClone = JSON.parse(JSON.stringify(obj));

 

그러나 이 방법에는 다음과 같은 단점이 있습니다.

  • 숫자, 문자열, 배열 및 일반 객체 이외의 값은 복제할 수 없습니다.
  • Date 및 Map 유형은 복제할 수 없습니다.
  • 처리 시간 및 메모리 사용량 면에서 비효율적입니다.
  • 재귀 구조가 있는 경우 사용할 수 없습니다.

 

StructuredClone

structuredClone 함수는 깊은 복사를 수행하기 위한 전용 함수입니다.

이 함수를 사용하면 JSON을 사용한 기존 방법의 단점을 해결할 수 있습니다.

 

JSON과 비교하여 이점은 다음과 같습니다.

  • 더 많은 유형이 복제 가능합니다.
  • 복제 가능한 유형 목록
  • 처리 시간 및 메모리 사용량 면에서 더 효율적입니다.
  • 재귀 구조가 있는 경우에도 작동합니다.

 

structuredClone 함수는 모든 주요 브라우저에서 사용할 수 있습니다.

728x90