일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 리액트
- javascript
- 네트워크
- cs #네트워크
- BFS
- 타입스크립트
- 프로그래머스
- 알고리즘
- react-query
- 개발자부트캠프
- 프로세스
- 유데미
- typescript
- 메모리
- 해시
- html
- CS
- IT개발캠프
- 웅진씽크빅
- react
- 스나이퍼팩토리
- ip
- App Runner
- Algorithm
- 인사이드아웃
- #프로젝트캠프 #프로젝트캠프후기 #유데미 #스나이퍼팩토리 #웅진씽크빅 #인사이드아웃 #IT개발캠프 #개발자부트캠프 #리액트 #react #부트캠프 #리액트캠프
- 자바스크립트
- React.js
- 프로젝트캠프
- 스레드
- Today
- Total
Bin's Blog
얕은 복사와 깊은 복사 본문
들어가며
지난 주, 기본형 데이터와 참조형 데이터를 작성했을 때에 말한대로 오늘은 얕은 복사와 깊은 복사에 대해서 알아보는 시간을 가지려고 한다.
오늘 주제는, 실제로 내가 면접 때 받았던 질문이었고 내가 제대로 답변을 하지 못한 부분이다.
따라서 제대로 이해하고 넘어가야 하는 부분이다.
얕은 복사
얕은 복사는 바로 아래 단계의 값만 복사하는 방법이다. 객체의 첫 번째 레벨의 속성만 복사한다. 만약 그 속성의 값이 참조형(객체 또는 배열)이면 그 내부의 속성이나 요소는 복사되지 않는다는 뜻이다.
예시를 보자.
let obj = {
a: 1,
b: { c: 2, d: 3 },
e: [4, 5]
};
이 객체에 대한 첫 번째 레벨의 속성은 "a", "b", "e"이다.
만약 얕은 복사를 수행하면, "a", "b", "e"의 참조를 새 객체에 복사한다. 그러나 나머지 { c: 2, d: 3}, [4, 5]는 복사하지 않는다.
결과적으로, 얕은 복사를 통해 생성된 새 객체는 원본 객체와 첫 번째 레벨의 속성에 대해 독립적이다.
하나 더 예시를 들어보겠다.
let obj = {
a: 1,
b: { c: 2 },
};
let copiedObj = {
a: obj.a,
b: obj.b
};
copiedObj.a = 10;
// 1
console.log(obj.a)
copiedObj.b.c = 5;
// 5
console.log(object.b.c);
위의 코드에서 copiedObj.a의 값을 바꾼다고 해서 obj.a의 값은 변경되지 않는다. 이것은 copiedObj의 첫 번째 레벨의 속성의 a가 원본 객체 obj와 독립적이기 때문이다. 기본 데이터 타입의 값을 직접 복사하여, 원본과 복사본이 서로 독립적인 값을 갖게 된다.
그러나, b의 경우 a와 다르게 다른 객체를 참조하므로, 참조형의 주소를 복사하여, 원본가 복사본이 동일한 객체를 참조하게 된다. 그래서 복사본을 수정하면 원본도 값이 변경된다.
깊은 복사
깊은 복사는 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법이다.
위에서 살펴보았듯이 문제가 속성의 값이 참조형인 경우에 직접 복사가 이루어지지 않기 때문에, 독립적인 값을 가지지 못하게 되면서 복사본의 값을 변경하면 원본의 값도 변경되는 현상이 발생했다.
이런 현상들을 해결하기 위해서 몇 가지 방법이 존재하는데 2가지만 살펴보겠다.
1.JSON 메소드
이 방법은 단순함에도 불구하고 잘 동작한다. 다만 메서드(함수)나 숨겨진 프로퍼티인 __proto__나 getter/setter 등과 같이 JSON으로 변경할 수 없는 프로퍼티들은 모두 무시한다.
httpRequest로 받은 데이터를 저장한 객체를 복사할 때 등 순수한 정보만 다룰 떄 활용하기 좋은 방법이다.
예시
let copyObjectViaJSON = (target) => {
return JSON.parse(JSON.stringify(target));
}
let obj = {
a: 1,
b: {
c: null,
d: [1, 2],
}
}
let obj2 = copyObjectViaJSON(obj);
obj2.a = 3;
obj2.b.c = 4;
obj.b.d[1] = 3;
// { a: 1, b: { c: null, d: [1, 3]} }
console.log(obj);
// { a: 3, b: { c: 4, d: [1, 2]} }
console.log(obj2);
2.외부 라이브러리 사용
"lodash"와 같은 외부 라이브러리에는 깊은 복사 기능이 내장되어 있다.
예시
const _ = require('lodash');
let copiedObj = _.cloneDeep(obj);
마무리하며
오늘 이렇게 얕은 복사와 깊은 복사에 대해서 공부를 하면서 개인적으로 아쉬움이 많이 남는다.
오늘 주제는 자바스크립트 기초 영역에 해당하는 부분인데, 내가 제대로 공부하지 않았던 부분에 대해서 지금도 깊은 반성의 시간을 가지고 있다. 지난 면접에서 나는 답변을 하는 내 모습을 마치 제3자의 입장으로 지켜보면서 질문에 대한 깊이 있는 고민의 흔적이 보이지 않았다는 것을 새삼 깨달았다. 쉽게 생각했고 성의 없었던 나의 준비과정을 보면서 그렇게 하는 것이 내가 개발자로서 성장하는데 하나도 도움이 되지 않는다는 것을 알게 되면서 끊임없이 고민하며 부족한 것을 채워 나가고 싶다.
'JavaScript' 카테고리의 다른 글
생각하는 자바스크립트 2편 - 자바스크립트의 역사 (0) | 2023.11.17 |
---|---|
생각하는 자바스크립트 1편 - 프로그래밍이란? (0) | 2023.11.07 |
기본형 데이터와 참조형 데이터 (0) | 2023.10.24 |
JS Framework & Library 트렌드 (0) | 2023.10.14 |
Garbage collection (0) | 2023.09.18 |