#back_to_basic
다시 처음부터!라는 마음으로 공부해보자! 아자아자!
1. 얕은 복사와 깊은 복사
미리 결론을 정리해보면,
얕은 복사는 객체의 참조값을 복사하고, 깊은 복사는 객체의 실제 값을 복사하는 것이다.
자바스크립트에서 값은 원시값과 참조값 두가지 데이터 타입의 값이 존재하는데,
- 원시값
- 기본 자료형을 의미(number, string, boolean, null, undefined 등)
- 변수에 원시값을 저장하면 변수의 메모리 공간에 실제 데이터 값이 저장되고, 할당된 변수를 조작하려고 하면 실제 값이 조작된다.
- 참조값
- 여러 자료형으로 구성되는 메모리에 저장된 객체
- object, symbol 등
- 변수에 객체를 저장하면 독립적인 메모리 공간에 값을 저장하고 변수에 저장된 메모리 공간의 참조를 저장하게 된다. 그래서 할당된 변수를 조작하는 것은 사실 객체 자체를 조작하는 것이 아닌, 해당 객체의 참조를 조작하는 것이다.
원시값을 복사할 때 그 값은 또 다른 독립적인 메모리 공간에 할당되기 때문에,
복사를 하고 값을 수정해도 기존 원시값을 저장한 변수에는 영향을 끼치지 않는다.
이처럼 실제 값을 복사하는 것을 깊은 복사라고 한다.
참조값을 복사할 때는 변수가 객체의 참조를 가리키고 있기 때문에 복사된 변수도 객체가 저장된 메모리 공간의 참조를 가리키고 있다.
그래서 복사를 하고 객체를 수정하면 두 변수는 똑같은 참조를 가리키고 있기때문에 기존 객체를 저장한 변수에 영향을 끼친다.
이처럼 객체의 참조값(메모리의 주소값)을 복사하는 것을 얕은 복사라고 한다.
객체를 복사할 때 위처럼 = 을 사용하여 복사하면, 얕은 복사가 되기때문에 기존 변수또한 수정이 된다.
JavaScript에서 얕은 복사와 깊은 복사를 하는 코드 예제들은 이 블로그에 아주 잘 정리가 되어있다.
2. Javascipt 불변성
흔히들 react state를 업데이트할 때 '불변성'을 지키라고 하는데, 왜 지켜야할까...?
일단 이론적으로는,
불변성을 지키지 않으면 사용할 데이터가 어디서 어떻게 바뀌어가는지 흐름을 쫓아가기 어렵고,
이는 예기치 못한 side effect나 버그를 발생하게 된다.
애초에 리액트에서 강조되는 불변성이라는 개념은, state와 props를 이용하여 불변성을 지킬 수 있도록 도와주는 것이다.
위 코드는 a에 10을 할당하고, b를 a가 가리키는 주소를 가리킨다.
a의 값을 변경시켜주었지만,
자바스크립트에서 Number값은 불변성을 유지하기때문에 새롭게 20이라는 값을 가지는 주소를 a에 할당하게 되어서 위와 같이 a와 b가 다른 값으로 출력되게된다.
위 1번에서 object는 원시값에 포함되지 않았는데,
이는 변경이 가능하다는 뜻이다.
이 말은 또, 객체는 객체 내부의 값을 변경하면 객체를 참조하고 있는 다른 값들도 다 같이 변경된다는 의미이다.
아래 코드를 보자.
위를 보면 coke의 name을 변경했는데, coke와 new_coke 모두 변경된 것을 볼 수 있다.
❓ 그렇다면 불변성을 지킨다는 의미는
일단 불변성을 지킨다는 의미는 '기존의 값을 직접적으로 수정하지 않고 새로운 값을 만드는 것'을 의미한다.
기존의 객체에 영향을 주지 않으면서, 새로운 곳에 객체를 복사하고 싶을 때는,
레퍼런스를 참조한 다른 객체에서 객체를 변경하지 않도록 해야한다.
객체를 불변 객체로 만들고, 객체의 변경이 필요한 경우에는 레퍼런스를 참조하는 것이 아닌 복사를 통해 새로운 객체를 생성한 후 변경하여 사용해야한다.
결론적으로,
객체는 참조에 의해 복사되므로, 객체의 불변성을 꼭 지켜야한다.
불변성을 지키는 수단으로는 객체의 얕은 복사와 깊은 복사가 존재하는데,
얕은 복사로는 중첩된 객체를 완전하게 복사할 수 없으므로, 깊은 복사를 사용해야한다.
불변성을 지키기 위해서는, spread 구문을 사용하거나, immer 같은 모듈, structuredCloe(내장 함수, node 17버전 이상)을 사용할 수 있다.
(참고로, spread를 사용하면, 객체 내부에 또 객체가 있을 경우 얕은 복사에 한계가 있다)
References
- Immutability 불변성
- 객체의 불변성을 지키는 방법
- 리액트 전역상태관리 리덕스
- 깊은 복사, 얕은 복사(https://bbangson.tistory.com/78)
- 불변성(https://velog.io/@co_mong/JS-%EB%B6%88%EB%B3%80%EC%84%B1Immutability)
- 자바스크립트에서 불변성이란(https://sustainable-dev.tistory.com/156)
- JavaScript 객체와 불변성(https://eun-ng.tistory.com/58)
(갑자기...링크 넣는 버튼이 안눌러진다.....뭐야 티스토리!)
오늘도 무튼 화이팅이다!
'Web' 카테고리의 다른 글
[BB] React Life Cycle와 useEffect (0) | 2023.12.13 |
---|---|
[BB] useRef가 사용되는 경우 (0) | 2023.12.08 |
[BB] 브라우저의 렌더링과 Virtual DOM (1) | 2023.10.25 |
[BB] Javascript: 비동기 프로그래밍 (0) | 2023.10.25 |
[BB] JavaScript: var, let, const의 차이 (0) | 2023.10.25 |