저는 현재 1년 3개월차 주니어 프론트엔드 개발자입니다.
뜬금없이 회사 프로젝트 외적으로 자바스크립트 공부를 하다가,
제가 이해한 깊은복사(Deep Copy) / 얕은복사(shallow Copy)를 정리하려고 글을 써봅니다.
먼저 자바스크립트에서 객체(Object)와 배열(Array)은 참조 타입(Reference Type)입니다.
쉽게말해 데이터가 할당되면, 해당 변수에는 실제 데이터가 아닌 메모리 주소가 저장된다는 의미입니다.
객체를 다른 변수에 할당할 시, 해당 변수는 객체의 메모리 주소를 참조 합니다.
두 변수는 같은 메모리의 객체를 가리키게 되고, 하나의 변수를 통해 객체를 수정하면 다른 변수에서도 그 변경 사항을 반영하게 됩니다.
const 오브젝트 = { name: "velog" }; // 100번지 메모리
const 오브젝트2 = 오브젝트 // 100번지 메모리
오브젝트2.name = "velog2"
console.log(오브젝트.name) // velog2
console.log(오브젝트2.name) // velog2
얕은 복사는 객체의 최상위 프로퍼티만 복사하며, 중첩된 객체는 여전히 참조로 복사됩니다.
즉, 복사된 객체의 중첩된 값이 변경되면 원본 객체에도 영향을 미칩니다.
얕은복사는 보통 스프레트문법을 이용합니다.
const 오브젝트 = {
name: "velog",
depth: {
depth1 : 10
}
};
const 오브젝트2 = {...obj} // 얕은복사 발생
오브젝트2.depth.depth1 = 20;
console.log(오브젝트.depth.depth1) // 20
console.log(오브젝트2.depth.depth1) // 20
위 코드에서 스프레드연산자를 사용해 얕은 복사를 했지만, 중첩된 객체 depth는 참조로 복사되어 오브젝트2.depth.depth1를 수정하면 오브젝트.depth.depth1도 동일하게 변경됩니다.
깊은 복사는 중첩된 객체도 완전히 새로운 객체로 복사됩니다.
이로 인해 복사된 객체의 변경 사항이 원본 객체에 영향을 미치지 않습니다. (불변성)
깊은 복사는 재귀적으로 직접복사하거나, JSON.stringify와 JSON.parse를 통해 문자열로 변환한 후 다시 객체로 변환하여 새로운 객체를 반환 시킬 수 있습니다. 아래 예시는 JSON 이용
const 오브젝트 = {
name: "velog",
depth: {
depth1 : 10
}
};
const 오브젝트2 = JSON.parse(JSON.stringify(오브젝트)) // 깊은복사 발생
오브젝트2.depth.depth1 = 20;
console.log(오브젝트.depth.depth1) // 20
console.log(오브젝트2.depth.depth1) // 10
위 코드에서는 JSON.stringify()로 문자열로 치환 후 JSON.parse()를 사용하여 객체로 변환하여 깊은 복사를 수행했습니다.
결과 값에서 보이는것과 같이 깊은복사를 하면 원본 오브젝트 객체의 값이 변경되지 않은 걸 알 수 있습니다.