본문 바로가기

study/JavaScript

Js - 불변성(immutability) React와 Vue의 불변성 차이

1. 불변성이란?
2. JavaScript 메모리 구조
3. 원시타입과 참조 타입의 데이터 저장방식과 재할당 비교
4. React와 Vue에서의 데이터 불변성

1. 불변성이란?

불변성은 값이나 상태를 변경할 수 없는 것을 의미한다. 프로그래밍에서 불변성은 데이터 원본의 훼손을 막는 것을 의미한다. 간단히 말하자면, 어떤 값을 직접적으로 변경하지 않고 새로운 값을 만들어내는 것이다.

2. JavaScript 메모리 구조

자바스크립트 엔진은 call stackheap memory 2가지 메모리 공간을 가지고있다.

call stack: 실행 중인 함수를 추적해 계산을 수행하고 지역변수를 저장하는 공간이다. 이곳에 원시 타입들이 저장된다.

heap memory참조 타입들이 할당되는 곳입니다. 메모리 누수를 방지하기 위해 js 엔진의 메모리 관리자가 항상 관리하는 공간입니다.

 

  • 원시 타입 : Boolean, String, Number, null, undefined, Symbol
  • 참조 타입 : Object, Array

 

원시 타입과 참조 타입 이 2가지 타입을 꼭 구별해야한다. 타입별로 데이터 저장방식과 할당 방식이 달라지기 때문이다.

 

3. 원시타입과 참조 타입의 데이터 저장방식과 재할당 비교

3-1. 원시 타입과 참조 타입의 데이터 저장방식

  • 원시 타입 : 변수 a에 값 10을 저장했을 경우 콜 스택의 값에 10이 그대로 저장된다.
  • 참조 타입 : 변수 b, c, d에 array, object를 저장할 경우 실제 값은 메모리 힙에 저장되고, 메모리 힙의 주소가 콜 스택의 값에 저장된다.

3-2. 변수 할당과 재할당

- 원시 타입의 특징

원시타입의 변수는 변수값을 변경하라는 명령을 받을 경우, 기존 콜스택의 값을 변경하지 않고 새로운 주소를 추가해 값을 저장하고 변수 b가 바라보게 한다. 이것을 불변성 이라고 한다. -> 메모리 영역의 값을 변경시키지 않고 새로운 메모리에 변경된 값을 저장

 

* 더이상 참조되지 않는 데이터는 GC에 의해 적절한 시점에서 메모리가 해제된다.

 

- 참조 타입의 특징

위에 이미지를 보며 변수를 할당하고 Js API인 push()함수를 통하여 값을 추가하면 원시 타입처럼 불변성이 지켜지지 않는다. 그 이유는 변수 a, b가 바라보고 있는 콜스택의 값이 변경되는것이 아닌, 메모리 힙에 있는 데이터가 변경이 되기 때문이다.

 

4. React와 Vue에서의 데이터 불변성

4.1 React

리액트에서는 불변성을 지켜야한다. 불변성을 지킨다는 의미는 메모리 영역에서 값을 변경할 수 없게 한다. 라고 정의할 수 있다. 리액트의 state 변화 감지 기준은 콜 스택의 주소값이기 때문에 불변성을 지켜야 데이터 변화를 감지하여 리렌더링을 할 수 있다.



원시 타입(Boolean, String, Number, null, undefined, Symbol)의 경우 값을 재할당할 경우 새로운 메모리가 할당되어 콜 스택의 주소 값이 변경된게 감지된다.

하지만 참조 타입(Object, Array 등등)의 경우 참조 타입의 값만 변경하면 콜 스택의 주소값은 변경이 없어 state 변경이 감지되지 않아 리렌더링이 되지 않는다. 그래서 참조 타입의 변수들은 spread operator, map, filter, slice, reduce 등등 새로운 배열을 반환하는 메소드들을 활용하여 불변성을 지켜야한다.

 

4.2 Vue

Vue는 data로 관리되는 객체의 속성을 직접적으로 변경하는 것을 허용한다. 즉, 불변성을 지키지 않아도 state 변화를 감지할 수 있다. Vue는 data로 객체를 관리할 때 모든 내부 속성에 대해 getter/setter를 달아두며, 이 getter/setter의 역할은 데이터의 변경이 일어날 때 Vue에게 알리는 기능을 한다. 따라서, state에 새로운 객체를 추가하면, Vue는 모든 상태를 모니터링해서 변경이 일어날 때마다 자동으로 DOM을 리렌더링 한다.