본 글은 공부하면서 작성한 글로, 너무 깊게는 들어가지 않으려 합니다.
그리고 많은 부분을 리액트와 연관지어 작성할 예정입니다.
최신 ECMAScript 표준은 다음과 같은 자료형을 정리한다.
보통 기본형과 참조형이라 나누어 부르기도 하며, 객체는 object
Array
Function
Date
WeakMaps
Maps
Sets
등을 일컫는다.
변수(variable). 여기서 변수란 데이터 할당을 통해 변할 수 있는 어떤 것 이라 할 수 있다.
let foo;
foo = 1;
let bar = 1;
첫번째 줄에서는 변수 foo
를 선언하고 있으며, 두번째 줄에서는 변수 foo
에 데이터를 할당하고 있다.
세번째 줄은 선언과 할당을 동시에 하고 있다.
변수를 선언하면, 컴퓨터는 메모리에서 비어있는 공간을 확보하고, 이 공간의 이름을 foo
라고 지정한다.
그 다음, 변수에 데이터를 할당하면 데이터를 저장하기 위한 메모리 공간을 확보한 후 1을 저장하고, foo
는 해당 메모리의 주소를 참조한다.
만약, 10 이라는 데이터로 재할당 한다면, 10이라는 데이터가 있는지 체크한 후 없으면 메모리 공간을 확보해 10을 저장할 것이다. 그리고 foo
는 새로 만들어진 메모리의 주소를 참조하게 될 것이다.
그렇다면 객체를 할당할 때는 어떨까?
let foo = { name: 'John', age: 1 }
변수는 총 3가지다. foo
, name
, age
각 변수명을 가진 메모리 공간이 확보될 것이고,
foo
는 name
과 age
를 프로퍼티로 가진 데이터 그룹의 주소를 참조하게 될 것이다.
그리고 위 데이터 그룹은 name
과 age
라는 공간의 주소를 참조하게 될 것이다.
이와 같이 참조-참조를 하기 때문에 name
의 값을 바꾼다고 해도 foo
의 값에는 영향을 주지 못한다.
foo
가 참조하는 주소값을 변경시키려면, let foo = { name: 'James', age: 1' } 과 같이 새로운 객체를 할당해야 한다.
리액트는 함수형 프로그래밍을 지향하고, 함수형 프로그래밍에서는 데이터가 변할 수가 없는데, 이를 불변성이라 한다. 불변성은 리액트 뿐만 아니라 Vue.js 나 Angular 등의 라이브러리나 프레임워크에서도 사용되는 개념이다.
객체는 참조를 통해 공유되고 있고, 그 상태는 언제든지 변경될 수 있기 때문에 문제가 발생할 여지가 있다. 객체를 참조하는 모든 장소에서 영향을 받기 때문이다.
이런 현상을 막기 위해 객체를 복사하여 새로운 객체를 생성한 후 변경해야 한다.
자바스크립트에서는 원본 객체의 불변성을 유지하게 도와줄 메서드로 Object.assign 을 제공하고 있다.
불변성을 유지하면 복제나 비교를 위한 조작을 단순화 할 수 있다.
하지만, Object.assign은 객체를 얕은 복사(shallow copy)를 한다.
즉, 바로 아래단계의 객체의 주소값만 복사하기 때문에, 중첩된 객체들의 주소값들은 복사하지 못한다.
깊은 복사(deep copy)를 하려면 재귀적으로 객체를 복사하는 메서드를 만들거나, 라이브러리를 이용하거나, JSON.parse(JSON.stringify(foo)) 과 같이 JSON 형식으로 바꾸고 다시 파싱을 해야 한다.
test