[자바스크립트] 얕은 복사 vs 깊은 복사(Feat. structuredClone())

이윤우·2023년 3월 8일
0

JavaScript

목록 보기
21/34
post-thumbnail

서론

자바스크립트는 기본적으로 얕은 복사를 구현하게끔 되어 있습니다. 만약 깊은 복사가 필요한 경우 여러 차선책들과 라이브러리에 의존해야 했습니다.

structuredClone()이라는 함수가 Web API로 지원되기 시작했습니다.

객체의 할당


객체 변수는 메모리 어딘가에 저장되어 있는 객체를 참조할 수 있는 값을 저장하고 있습니다.
따라서 객체를 단순하게 변수 할당 방식으르 설정하는 경우, 동일한 객체를 참조하며 사실상 동일한 하나의 "객체"를 가리키게 됩니다.

얕은 복사

1차원적인 단순 객체의 경우 비교적 간단하게 복사할 수 있습니다. 대표적으로 Object.assignspread operator를 이용하는 방법이 있습니다.

const clonedCat = {
	name: 'cookie',
  	age: 2,
};

const clonedCat = Object.assign({}, cat); // or {...cat}
clonedCat.age = 3;

console.log(cat);        // { name: 'cookie', age: 2 }
console.log(clonedCat)   // { name: 'cookie', age: 3 }

하지만 객체 내부에 또 다른 객체가 있거나 배열이 존재하는 등의 경우엔 해당 부분은 여전히 원본의 내용을 참조하게 됩니다.

const cat = {
	profile: {
    	name: 'cookie',
      	age: 2,
    },
  	butler: '김메조',
}

const clonedCat = {...cat};
clonedCat.profile.age = 3;
clonedCat.butler = '김미디어';

console.log(cat);        // { profile: { name: 'cookie', age: 3 }, butler: '김메조' }
console.log(clonedCat)   // { profile: { name: 'cookie', age: 3 }, butler: '김미디어' }

이러한 복잡한 객체 구조에 대한 복사를 위해서는 깊은 복사를 해야 합니다.

깊은 복사

1) JSON 메서드

JSON.stringify()JSON.parse()를 사용하여 객체 -> 스트링 -> 객체의 변환 과정을 통해 깊은 복사를 수행할 수 있습니다.

제한 사항

  • Recursive data structures (연결 리스트, 트리 구조 ...)
  • Built-in types (Date, Map, Set, RexExp ...)
  • Functions
const cat = {
	profile: {
    	name: 'cookie',
      	age: 2,
    },
  	butler: '김메조',
}

const clonedCat = JSON.stringify(JSON.parse(cat));

2) Lodash의 cloneDeep() 함수

const cat = {
	profile: {
    	name: 'cookie',
      	age: 2,
    },
  	butler: '김메조',
}

const clonedCat = _.cloneDeep(cat);

3) structuredClone() 함수

structuredClone()JSON.stringify()의 많은 단점을 해결해줍니다. 순환되는 데이터 구조를 처리할 수 있고, 내장 데이터 타입을 지원할 수 있으며 일반적으로 더 강력하고 더 빠릅니다.

const cat = {
	profile: {
    	name: 'cookie',
      	age: 2,
    },
  	butler: '김메조',
}

const clonedCat = structuredClone(cat);

제한 사항

  • 프로토타입: 클래스 인스턴스와 함께 사용하는 경우, structuredClone()이 프로토타입 체인을 폐기하므로 반환 값은 일반 객체가 됩니다.
  • Functions
  • DOM 노드

0개의 댓글