강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

얄라차개발자님의 프로필 이미지
얄라차개발자

작성한 질문수

React 완벽 마스터: 기초 개념부터 린캔버스 프로젝트까지

Deep Copy vs Shallow Copy

얕은복사와 깊은복사 질문

작성

·

109

1

안녕하세요. 얕은복사와 깊은복사에 대해 질문합니다.
제가 알기론 지금 예시를 든
let person1 = {firstName:'짐', lastName:'코딩'};
let person2 = {...person1};
person1.firstName = 'GYM'
console.log('person1: ', person1);

console.log('person2: ', person2);
이거를 깊은 복사라고 하셨는데
얕은 복사 아닌가여?? 값이 원시값이라서 참조 공유 문제가 안생기는거 아닌가요??
깊은 복사는 모든 깊이까지 값 자체를 완전하게 복사해야되는걸로 알고 있어서 cloneDeep이나 JSON.parse(JSON.stringify(person1)) 이런식으로 써야되는걸로 알고 있거든여.
const items = [...todos] 도 얕은 복사지만 새로운 배열 주소를 만들어서 리액트에서는 변화가 생겼다고 판단하고 리렌더링이 되는걸로 알고 있는데 아닌가요??

답변 2

2

짐코딩님의 프로필 이미지
짐코딩
지식공유자

정말 좋은 지적입니다! 👍

맞습니다. 기술적으로 정확히 말하면 스프레드 연산자(...)는 얕은 복사(shallow copy)를 수행합니다. 강의에서 설명드린 예시:

let person1 = {firstName:'짐', lastName:'코딩'};
let person2 = {...person1};
person1.firstName = 'GYM'

이 예시에서는 객체가 원시값만 포함하고 있어서 깊은 복사와 동일한 결과를 보여주지만, 개념적으로는 얕은 복사가 맞습니다.

만약 중첩 객체가 있었다면 차이가 명확히 드러났을 겁니다:

let person1 = {firstName:'짐', lastName:'코딩', address: {city: '서울'}};
let person2 = {...person1};
person1.address.city = '부산';
console.log(person2.address.city); // '부산' (참조가 공유되므로 변경됨)

질문자님 말씀대로 진정한 깊은 복사는 lodashcloneDeep()이나 JSON.parse(JSON.stringify()), 최근의 structuredClone() 메서드를 사용해야 합니다.

다음 회차에서 스프레드 연산자가 중첩된 객체를 깊은 복사하지 않는 다는 것으로 설명을 했지만 이번 회차설명에서 보면 틀린 부분이 있어요 👍

그리고 React에서 const items = [...todos]에 대한 이해도 정확합니다! 새 배열 참조를 만들기 때문에 React가 상태 변화를 감지할 수 있습니다.

이렇게 세심하게 짚어주셔서 감사합니다. 해당 강의 회차에서 Deep Copy vs Shallow Copy 부분을 기초부터 완전한 깊은 복사 까지 제대로 설명하는 것으로 영상을 수정하도록 할게요 🙂

감사합니다 👍

1

안녕하세요, 인프런 AI 인턴입니다.

얄라차개발자님, 얕은 복사와 깊은 복사에 대한 혼란이 있을 수 있는데요, 설명드리겠습니다.

  1. 얕은 복사 (Shallow Copy):

    • 객체의 최상위 레벨의 속성들만 복사합니다. 이 경우, 중첩 객체나 배열 내부의 객체들은 참조가 그대로 복사됩니다.
    • 예시: let person2 = {...person1};라는 문장은 person1의 최상위 레벨 속성들을 복사하지만, 중첩 객체들이 있을 경우 이들은 참조로 남아 있게 됩니다. 따라서 중첩 객체는 서로 연결되어 있어, 중첩 객체의 속성을 수정 시 두 객체 모두 영향을 받을 수 있습니다.
  2. 깊은 복사 (Deep Copy):

    • 객체 구조 내 모든 레벨의 속성을 재귀적으로 복사하여 독립적인 새로운 객체를 만듭니다.
    • 일반적으로 cloneDeep 또는 JSON.parse(JSON.stringify(obj))와 같은 방법을 사용합니다.

얄라차개발자님이 제시해 주신 예제에서는 person1person2 모두 최상위 레벨 속성만 복사되었기 때문에 얕은 복사가 맞습니다. JSON.parse(JSON.stringify(person1))을 사용한 방법이 깊은 복사에 해당합니다.

React에서는 const items = [...todos]처럼 새로운 배열을 생성하더라도 내부 객체가 참조로 남아 있으면 얕은 복사가 됩니다. 그러나 배열의 레퍼런스가 변경되었기 때문에 React는 이를 새로운 값으로 인식하여 렌더링을 트리거합니다.

문제에 대한 자세한 설명 및 관련 토론은 React 깊은 복사와 얕은 복사에 대한 논의에서 확인하실 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

얄라차개발자님의 프로필 이미지
얄라차개발자

작성한 질문수

질문하기