본문 바로가기

자바스크립트

자바스크립트) 객체의 복사

이 글은 아래 링크
https://web.dev/structured-clone/ 

 

Deep-copying in JavaScript using structuredClone

For the longest time, you had to resort to workarounds and libraries to create a deep copy of a JavaScript value. The Platform now ships with structuredClone(), a built-in function for deep-copying.

web.dev

를 보고 의역한 글입니다

 

 

최근 객체를 복사할 일이 생겨 이에 대해 알아보는 시간을 가져보았습니다.

 

자바스크립트에서 객체를 복사하는 방법은 몇가지가 존재합니다

얕은 복사본

개체 스프레드 연산자를 사용하여 JavaScript에서 얕은 복사본을 만드는 한 가지 방법 ...:

 

const myOriginal = {
  someProp: "with a string value",
  anotherProp: {
    withAnotherProp: 1,
    andAnotherProp: true
  }
};

const myShallowCopy = {...myOriginal};

얕은 복사본에서 직접 속성을 추가하거나 변경하면 복사본에만 영향을 미치고 원본에는 영향을 미치지 않습니다.

myShallowCopy.aNewProp = "a new value";
console.log(myOriginal.aNewProp)
// ^ logs `undefined`

그러나 깊게 중첩된 속성을 추가하거나 변경하면 복사본과 원본 모두에 영향을 미칩니다.

myShallowCopy.anotherProp.aNewProp = "a new value";
console.log(myOriginal.anotherProp.aNewProp) 
// ^ logs `a new value`

표현식은  Spread Operator 사용 {...myOriginal}  의 속성을 반복합니다. 속성 이름과 값을 사용하고 새로 만든 빈 개체의 하나씩 할당합니다.

따라서 결과 개체는 모양이 동일하지만 속성 및 값 목록의 자체 복사본이 있습니다. 값도 복사되지만 소위 기본 값은 기본 값이 아닌 값과 JavaScript 값에 의해 다르게 처리됩니다.

 

깊은 복사

얕은 복사의 반대는 깊은 복사입니다. 깊은 복사 알고리즘도 개체의 속성을 하나씩 복사하지만 다른 개체의 대한 참조를 찾으면 자체적으로 호출하여 해당 개체의 복사본을 만듭니다.

이것은 두 개의 코드 조각이 실수로 객체를 공유하지 않고 무의식적으로 서로의 상태를 조작하지 않도로 하는 데 매우 중요합니다.

이전에는 JavaScript에서 값의 깊은 복사를 생성하는 쉽고 좋은 방법이 있습니다. 대표적으로

Lodash라이브러리의 cloneDeep() 있습니다.

라이브러리를 사용하지 않는 방식은 다음이 있습니다.

const myDeepCopy = JSON.parse(JSON.stringify(myOriginal));

개체를 직렬화 한 다음 JSON.parse로 역직렬화합니다.

하지만 이 방법은 문제가 있습니다.

myDeppCopy개체를 콘솔로그로 찍어보면,

    const myOriginal = {
      someProp: "with a string value",
      anotherProp: {
        withAnotherProp: 1,
        andAnotherProp: true,
      },
      date: new Date("2023-01-01"),
      arr: ["korea", "usa"],
    };

    const myDeepCopy = JSON.parse(JSON.stringify(myOriginal));
    console.log(myDeepCopy);

 

Date 객체여야 할 myDeepCopy.date가 date객체가 아닌 string으로 나옵니다.

이 이유는 직렬화, 역직렬화 과정에서는 배열,객체 등과 같은 원시 타입만 다루기 때문입니다.

이를 위해서라도 structuredClone() 을사용해야 합니다

const myDeepCopy = structuredClone(myOriginal);

 

This is It....!

이것이 전부입니다. 더 자세히 알아보려면 MDN기사를 살펴보세요.

 

기능 및 제한 사항

구조화된 복제는 기술의 많은(Not All) 단점을 해결합니다.

구조적 복제는 순환 데이터 구조를 처리하고 많은 기본 제공 데이터 유형을 지원할 수 있으며 일반적으로 더 강력하고 더 빠릅니다.

그러나 여전히 다음과 같은 몇가지 제한이 있습니다.

  • 프로토타입 : 클래스 인스턴스와 함께 사용하는 경우 structuredClone()구조화된 복제가 객체의 프로토타입 체인을 버리기 때문에 반환 값을 일반 객체를 얻게됩니다.
  • 기능 : 개체의 기능이 포함되어 있으면 자동으로 폐기됩니다.
  • Non-cloneables : 일부 값은 구조적으로 복제할 수 없으며 특히 Error Dom 노드입니다. structuredClone() 던지는 원인이 됩니다.

이러한 제한 사항이 사용 사례에 대한 거래 차단기인 경우 Lodash와 같은 라이브러리는 여전히 사용 사례에 적합하거나 적합하지 않을 수 있는 다른 심층 복제 알고리즘의 사용자 지정 구현을 제공합니다.

 

성능

변경 불가능한 데이터 구조를 사용하거나 함수가 원본에 영향을 주지 않고 개체를 조작할 수 있도록 하기 위해 JS에서 값의 전체 복사본을 생성해야 하는 경우 더 이상 해결 방법을 찾을 필요가 없습니다. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ㄱfeafeafdddfeafeafea