작성
·
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); // '부산' (참조가 공유되므로 변경됨)
질문자님 말씀대로 진정한 깊은 복사는 lodash
의 cloneDeep()
이나 JSON.parse(JSON.stringify())
, 최근의 structuredClone()
메서드를 사용해야 합니다.
다음 회차에서 스프레드 연산자가 중첩된 객체를 깊은 복사하지 않는 다는 것으로 설명을 했지만 이번 회차설명에서 보면 틀린 부분이 있어요 👍
그리고 React에서 const items = [...todos]
에 대한 이해도 정확합니다! 새 배열 참조를 만들기 때문에 React가 상태 변화를 감지할 수 있습니다.
이렇게 세심하게 짚어주셔서 감사합니다. 해당 강의 회차에서 Deep Copy vs Shallow Copy 부분을 기초부터 완전한 깊은 복사 까지 제대로 설명하는 것으로 영상을 수정하도록 할게요 🙂
감사합니다 👍
1
안녕하세요, 인프런 AI 인턴입니다.
얄라차개발자님, 얕은 복사와 깊은 복사에 대한 혼란이 있을 수 있는데요, 설명드리겠습니다.
얕은 복사 (Shallow Copy):
let person2 = {...person1};
라는 문장은 person1
의 최상위 레벨 속성들을 복사하지만, 중첩 객체들이 있을 경우 이들은 참조로 남아 있게 됩니다. 따라서 중첩 객체는 서로 연결되어 있어, 중첩 객체의 속성을 수정 시 두 객체 모두 영향을 받을 수 있습니다.깊은 복사 (Deep Copy):
cloneDeep
또는 JSON.parse(JSON.stringify(obj))
와 같은 방법을 사용합니다.얄라차개발자님이 제시해 주신 예제에서는 person1
과 person2
모두 최상위 레벨 속성만 복사되었기 때문에 얕은 복사가 맞습니다. JSON.parse(JSON.stringify(person1))
을 사용한 방법이 깊은 복사에 해당합니다.
React에서는 const items = [...todos]
처럼 새로운 배열을 생성하더라도 내부 객체가 참조로 남아 있으면 얕은 복사가 됩니다. 그러나 배열의 레퍼런스가 변경되었기 때문에 React는 이를 새로운 값으로 인식하여 렌더링을 트리거합니다.
문제에 대한 자세한 설명 및 관련 토론은 React 깊은 복사와 얕은 복사에 대한 논의에서 확인하실 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.