JavaScript

자바스크립트 깊은 복사 structuredClone()

citron031 2022. 10. 25. 12:48
  • Object.assign()과 spread operator, slice()를 사용한 복사는 얕은 복사이다.
  • 깊은 복사를 위해서 JSON.parse, JSON.stringify를 사용할 수 있으나 한게점이 있다.
  • JSON.parse, JSON.stringify를 사용하면, 객체 내부의 함수 등 일부 타입의 데이터가 소실될 수 있다.
  • 이런 문제점을 해결하는 새로운 문법이 structuredClone이다.
const a = [1, 2, 3];
const b = [...a];

console.log(a, b); // [1, 2, 3] [1, 2, 3]

const c = {a: "a", b: "b", c: "c"};
const d = {...c};

console.log(c, d); // { a: "a", b: "b", c: "c" } { a: "a", b: "b", c: "c" }

 

 

  • 하지만 위의 두 방법은 얕은 복사이다.
  • 내부의 배열이나 객체와 같은 참조형 변수의 값은 제대로 복사할 수 없다.

 

const a = [1, {"a" : 10}];
const b = [...a];

a[1].a = -7

console.log(a, b); // [1, {"a" : -7}] [1, {"a" : -7}]

const c = {a: "a", b: "b", c: [1, 2]};
const d = {...c};

c.c.push(-7);

console.log(c, d); // { a: "a", b: "b", c: [1, 2, -7] } { a: "a", b: "b", c: [1, 2, -7] }

 

 

  •  JSON.stringify와 JSON.parse를 연속으로 사용하여 복사할 수 있다.

 

const obj = {a: 1, b: [1]};
const obj2 = JSON.parse(JSON.stringify(obj));

obj.b.push(-8);

console.log(obj, obj2); // { a: 1, b: [1, -8] } { a: 1, b: [1] }

 

 

  • 다만, 함수등의 특수한 데이터는 복사할 수 없다.

 

const arr = [() => console.log("Hi"), () => {}];
const arr2 = JSON.parse(JSON.stringify(arr));

console.log(arr, arr2); // [() => console.log("Hi"), () => {}] [null, null]

 

 

  •  structuredClone는 JSON.parse, JSON.stringify을 이용한 깊은 복사의 단점을 해결한다.
  •  더 빠르고 Error와 같이 복사가 안되었던 변수의 복사도 지원한다.
  •  또한, structuredClone가 더 빠른 성능을 자랑한다.

const a = [1, 2, 3, {a: -4}];
const b = structuredClone(a);

a[3].b = "Kim";
b[3].c = "Lee";

console.log(a, b); // [1, 2, 3, {a: -4, b: "Kim"}] [1, 2, 3, {a: -4, c: "Lee"}]




참고 자료 : https://developer.mozilla.org/en-US/docs/Web/API/structuredClone

 

structuredClone() - Web APIs | MDN

The global structuredClone() method creates a deep clone of a given value using the structured clone algorithm.

developer.mozilla.org