inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

Deep Copy vs Shallow Copy

얕은복사와 깊은복사 질문

141

얄라차개발자

작성한 질문수 16

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] 도 얕은 복사지만 새로운 배열 주소를 만들어서 리액트에서는 변화가 생겼다고 판단하고 리렌더링이 되는걸로 알고 있는데 아닌가요??

react React-Context react-router tailwindcss react-query

답변 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 인턴

안녕하세요, 인프런 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 깊은 복사와 얕은 복사에 대한 논의에서 확인하실 수 있습니다.

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

오타?

0

27

1

뭐하나 여쭤봐도 될까요?

0

70

1

안녕하세요 질문이 있습니다.

0

55

2

질문 : 삭제 버튼 아규먼트 (id)

0

50

1

Tailwind 버전 확인

0

62

1

align-items 정렬

0

50

2

vite 명령어로 프로젝트를 만들었습니다. (vscode)

0

79

1

31. 객체 업데이트 하기 - 10:15 질문

1

55

2

강의교안, 내용 인용해서 블로그 글 작성

1

80

2

이미지가 출력되지 않아요

1

73

2

강의와 만들어진 코드가 달라요

0

75

3

AI와 CSS 라이브러리의 궁합

0

95

1

onClick 이벤트에 함수 넘길 때

0

64

1

린캔버스 기능 구현은 왜 못하나요.... 구현하고 싶습니다...

0

101

1

notes 없음 읽기 오류

0

72

1

Object.assign 문법

0

64

1

react-router 전혀 기능 안함

0

53

1

react-router-dom@6.25.1

0

47

1

React Router 최신 스펙

0

207

1

Immer 에서 filter, map 사용

0

54

1

vite 설치에 대해 질문있습니다.

0

76

2

라이브러리 버전 일치 이슈

0

76

1

"Enter 키 발생 시 항목 추가" 부분에서 공백이 포함되면 한 줄이 더 입력됩니다

0

49

2

TotalCounter을 작성할때

0

65

2