깊은 복사와 얕은 복사의 개요
자바스크립트에서 객체를 복사할 때, 깊은 복사와 얕은 복사는 중요한 개념입니다.
이 둘의 차이를 이해하면 객체를 다룰 때 발생할 수 있는 문제를 미연에 방지할 수 있습니다.
관련 용어 및 개념 정의
- 깊은 복사: 객체의 모든 내용을 복사하여 완전히 새로운 객체를 생성하는 방식
- 얕은 복사: 객체의 주소를 복사하여 새로운 객체를 생성하는 방식
깊은 복사와 얕은 복사의 원본 데이터와 복사 데이터 비교
깊은 복사의 리턴값
깊은 복사를 사용하면 원본 객체와 완전히 독립적인 새로운 객체가 반환됩니다.
const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));
// 원본 데이터 변경
original.a = 3;
original.b.c = 4;
// 복사 데이터 변화 확인
console.log(deepCopy); // { a: 1, b: { c: 2 } }
// 원본 데이터와 복사 데이터 비교
console.log(original === deepCopy); // false
// 깊은 복사 확인
console.log(original.b === deepCopy.b); // false
original | 주소 A | 원본 객체 |
original.a | 주소 B | 원본 객체의 a 속성 (숫자) |
original.b | 주소 C | 원본 객체의 b 속성 (객체) |
shallowCopy | 주소 D | 원본 객체의 깊은 복사 |
shallowCopy.a | 주소 E | 깊은 복사된 객체의 a 속성 (숫자) |
shallowCopy.b | 주소 F | 깊은 복사된 객체의 b 속성 (객체) |
얕은 복사의 리턴값
얕은 복사를 사용하면 원본 객체의 참조만 복사되기 때문에 내부 객체는 동일한 객체를 참조합니다.
const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);
// 원본 데이터 변경
original.a = 3;
original.b.c = 4;
// 얕은 복사 데이터 변화 확인
console.log(shallowCopy); // { a: 3, b: { c: 4 } }
// 원본 데이터와 얕은 복사 데이터 비교
console.log(original === shallowCopy); // false
// 얕은 복사 확인
console.log(original.b === shallowCopy.b); // true
original | 주소 A | 원본 객체 |
original.a | 주소 B | 원본 객체의 a 속성 (숫자) |
original.b | 주소 C | 원본 객체의 b 속성 (객체) |
shallowCopy | 주소 D | 원본 객체의 얕은 복사 |
shallowCopy.a | 주소 B | 얕은 복사된 객체의 a 속성 (숫자) |
shallowCopy.b | 주소 C | 얕은 복사된 객체의 b 속성 (객체) |
깊은 복사와 얕은 복사의 사용 예시
실제 개발 상황에서 각각의 복사 방식을 어떻게 활용할 수 있는지 예시를 제시하겠습니다.
깊은 복사 사용 예시
깊은 복사는 객체를 완전히 독립적으로 복사하므로, 내부 객체까지 모두 새롭게 생성됩니다.
const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.b.c = 3;
console.log(original); // { a: 1, b: { c: 2 } }
console.log(deepCopy); // { a: 1, b: { c: 3 } }
얕은 복사 사용 예시
얕은 복사는 객체의 내부 객체까지 새롭게 생성하지 않으므로, 내부 객체의 값이 변경되면 원본 객체에도 영향을 미칩니다.
const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);
shallowCopy.b.c = 3;
console.log(original); // { a: 1, b: { c: 3 } }
console.log(shallowCopy); // { a: 1, b: { c: 3 } }
깊은 복사와 얕은 복사를 적용한 코딩 테스트 문제 풀이
깊은 복사와 얕은 복사의 개념을 활용하여 다양한 코딩 테스트 문제를 해결하는 과정을 살펴보겠습니다.
문제
주어진 객체를 얕은 복사하여 새로운 객체를 생성하고, 내부 객체의 값을 변경한 후 원본 객체와 복사본 객체를 출력하세요.
const original = { a: 1, b: { c: 2 } };
const shallowCopy = {...original};
shallowCopy.b.c = 3;
console.log(original); // { a: 1, b: { c: 3 } }
console.log(shallowCopy); // { a: 1, b: { c: 3 } }
해결 과정
- 주어진 객체를 얕은 복사하여 새로운 객체를 생성합니다.
- 새로운 객체의 내부 객체의 값을 변경합니다.
- 원본 객체와 복사본 객체를 출력합니다.
파이썬에서의 복사 방식 비교
자바스크립트와 파이썬에서는 객체를 복사하는 방식이 조금씩 다릅니다.
이에 따라서 각 언어에서의 깊은 복사와 얕은 복사의 구현 방식과 특징을 비교해보겠습니다.
파이썬에서의 깊은 복사와 얕은 복사
깊은 복사
파이썬에서 깊은 복사를 하려면 copy
모듈의 deepcopy()
함수를 사용합니다.
이 함수는 객체의 내부 객체까지 모두 새롭게 복사하여 완전한 복사를 수행합니다.
import copy
original = {'a': 1, 'b': {'c': 2}}
deep_copy = copy.deepcopy(original)
얕은 복사
파이썬에서 얕은 복사는 copy
모듈의 copy()
함수를 사용하거나 슬라이싱을 통해 구현할 수 있습니다.
얕은 복사는 주어진 객체의 주소를 복사하여 새로운 객체를 생성하므로, 내부 객체는 동일한 객체를 참조합니다.
import copy
original = {'a': 1, 'b': {'c': 2}}
shallow_copy = copy.copy(original)
깊은 복사를 위한 함수들
JSON.parse(JSON.stringify(object))
: 객체를 JSON 문자열로 변환한 뒤 다시 객체로 변환하여 깊은 복사를 수행lodash
라이브러리의cloneDeep()
: lodash 라이브러리의cloneDeep()
함수를 사용하여 객체를 완전히 복사immer
라이브러리의produce()
: 불변성을 유지하면서 객체를 변경하는데 사용되는 immer 라이브러리의produce()
함수는 객체의 깊은 복사를 지원rfdc
라이브러리의deepClone()
: rfdc 라이브러리의deepClone()
함수를 사용하여 객체를 깊은 복사할 수 있음clone
라이브러리의clone()
: clone 라이브러리의clone()
함수를 사용하여 객체를 깊은 복사할 수 있음cloneDeep
라이브러리의cloneDeep()
: cloneDeep 라이브러리의cloneDeep()
함수를 사용하여 객체를 깊은 복사할 수 있음immer
라이브러리의original()
: immer 라이브러리의original()
함수를 사용하여 객체를 깊은 복사할 수 있음deepcopy
라이브러리의deepcopy()
: deepcopy 라이브러리의deepcopy()
함수를 사용하여 객체를 깊은 복사할 수 있음fast-copy
라이브러리의copy()
: fast-copy 라이브러리의copy()
함수를 사용하여 객체를 깊은 복사할 수 있음clone
함수: 직접 재귀적으로 객체를 순회하면서 각 속성을 복사하여 새로운 객체를 생성하는 함수
얕은 복사를 위한 함수들
Object.assign()
: 객체의 속성을 다른 객체로 복사하여 얕은 복사를 수행spread
연산자 (...
): spread 연산자를 사용하여 객체를 얕은 복사할 수 있음Object.create()
: 주어진 객체를 프로토타입으로 하는 새로운 객체를 생성하여 얕은 복사를 수행Object.fromEntries(Object.entries(object))
: 객체의 키-값 쌍을 배열로 변환한 뒤 다시 객체로 변환하여 얕은 복사를 수행Object.keys()
와reduce()
:Object.keys()
를 사용하여 객체의 키를 배열로 가져온 뒤,reduce()
함수를 사용하여 새로운 객체를 생성하여 얕은 복사를 수행Object.getOwnPropertyDescriptors()
와Object.defineProperties()
: 객체의 속성 디스크립터를 가져와서 다른 객체의 속성에 적용하여 얕은 복사를 수행Object.entries()
와Object.fromEntries()
: 객체의 키-값 쌍을 배열로 변환한 뒤 다시 객체로 변환하여 얕은 복사를 수행Array.prototype.concat()
: 배열을 얕은 복사하여 새로운 배열을 생성Array.prototype.slice()
: 배열의 일부를 선택하여 얕은 복사하여 새로운 배열을 생성Array.from()
: 배열을 얕은 복사하여 새로운 배열을 생성
'Develop > JS' 카테고리의 다른 글
자바스크립트[JS] - 💯 문자열 치환 함수 replaceAll() 알아보기 (2) | 2024.03.23 |
---|---|
자바스크립트[JS] - 💯 하나만 만족해도 좋은 SOME() 함수 알아보기 (0) | 2024.03.22 |
자바스크립트[JS] - 💯 join() 알아보기 / 배열을 문자열로 (0) | 2024.03.19 |
자바스크립트[JS] - 💯 match() 알아보기 / 정규식 필수⭐ (0) | 2024.03.19 |
자바스크립트[JS] - 💯 sort() 함수 총정리 (0) | 2024.03.15 |