불변성 Immutability
안녕하세요! 오늘은 자바스크립트의 중요한 개념 중 하나인 "불변성"에 대해 알아보려 합니다.
다소 추상적인 개념인 불변성을 자세히 알아보기 위해서는 원시타입과 참조타입에 따라 자바스크립트 엔진이 어떻게 변화하는지에 대해서 짚고 넘어가야해요.
자바스크립트의 원시타입은 현재 총 7가지가 있지만, 기본적으로 많이 쓰이는 것은 Number, Null, String, Undefined, Boolean 타입이 있고,
참조타입으로는 Object, Array, Function 등이 있습니다.
보통 원시 타입은 불변하다고 하고, 참조 타입은 반대로 변한다고 표현합니다.
왜냐하면 데이터 저장 방식에 차이가 있기 때문입니다.
원시 타입의 경우 콜스택의 실제 값에 바로 담기게 되고, 참조 타입은 콜스택의 값이 메모리 주소를 가르키고, 메모리 힙 영역에 실제 값이 담기게 됩니다.
이런 경우 원시 타입은 변수를 재할당하게 되면 이전 값은 가비지 콜렉터의 대상으로, 새로운 값은 콜스택의 값에 담기게 됩니다.
여기서 이루어지는 메모리 재할당은 메모리 영역에는 아무 변동이 생기지 않습니다.
이 뜻은 바로 '메모리 힙 영역의 값은 변경되지 않았다. == 불변하다.' 라고 할 수 있습니다.
불변성이란 무엇인가요?
불변성이란 이름에서 알 수 있듯이, 데이터가 변경되지 않은 상태를 의미합니다.
즉, 한 번 생성된 데이터는 그 값을 절대로 변경할 수 없습니다. 이 개념은 자바스크립트에서 변수나 객체를 다룰 때 중요한 역할을 합니다.
왜 불변성을 유지해야 하나요?
1️⃣ 예측 가능한 코드:
데이터가 변경되지 않으면 코드의 동작도 예측 가능해집니다. 값이 변하지 않으므로 코드 실행 도중 의도치 않은 변경 사항이 발생할 위험이 줄어듭니다.
2️⃣ 성능 향상:
불변한 데이터는 변할 필요가 없으므로, 변경 시 발생하는 연산 비용을 줄일 수 있습니다. 이로써 코드 실행 속도가 향상됩니다.
3️⃣ 시간 여행 디버깅:
버그를 잡을 때 불변한 데이터는 문제 해결을 더 쉽게 만들어줍니다. 이전 상태로 돌아갈 필요 없이 해당 시점의 데이터를 그대로 분석할 수 있습니다.
어떻게 불변성을 유지할 수 있을까요?
1️⃣ 원시 데이터 타입 사용:
숫자나 문자열과 같은 원시 데이터 타입은 불변합니다. 변수 값을 갱신하려면 새로운 값을 할당해야 합니다.
2️⃣ 객체 복제:
객체를 다룰 때는 원본 객체를 직접 수정하지 않고, 새로운 객체를 만들어서 수정합니다. 이를 "깊은 복사"라고 부릅니다.
3️⃣ 불변성 라이브러리 활용:
자바스크립트에서는 불변성을 유지하기 위한 라이브러리들이 있습니다. 대표적으로 'Immutable.js' 나 'immer'가 있습니다.
불변성이 필요한 예시
불변성은 리액트와 같은 라이브러리에서 매우 중요합니다.
컴포넌트 간 데이터 전달 시, 데이터가 변경되지 않으면 성능 최적화 및 예측 가능한 동작을 보장할 수 있습니다.
또한 리덕스와 같은 상태 관리 라이브러리에서도 불변성을 지키면 상태 변화를 쉽게 추적하고 업데이트할 수 있습니다.
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="incrementCount">Increment</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
};
},
methods: {
incrementCount() {
// this.count를 직접 변경하지 않고 새로운 값을 할당합니다.
this.count += 1;
},
},
};
</script>
위 코드에서 incrementCount 메서드에서 this.count 값을 직접 변경하고 있습니다.
하지만 이렇게 하면 Vue의 리액티브 시스템에서 불변성이 유지되지 않아 예기치 않은 동작이 발생할 수 있습니다.
불변성을 지키기 위해서는 다음과 같이 수정할 수 있습니다.
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="incrementCount">Increment</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
};
},
methods: {
incrementCount() {
// 새로운 객체를 생성하여 변경합니다.
this.count = this.count + 1;
},
},
};
</script>
이제 incrementCount 메서드에서 this.count를 변경할 때 새로운 값을 할당하도록 변경하였습니다.
이렇게 하면 Vue가 컴포넌트의 상태를 올바르게 감지하고 업데이트를 처리할 수 있습니다.
마무리
불변성은 자바스크립트 개발에서 지켜야 할 중요한 원칙 중 하나입니다.
데이터를 변경하지 않고 새로운 데이터를 생성하며 코드를 작성하면 예측 가능하고 성능 최적화된 애플리케이션을 구축할 수 있습니다.
이 개념을 활용하여 보다 견고하고 유지보수가 용이한 코드를 작성해보세요!
'Front End' 카테고리의 다른 글
[번역] 실패하기 쉬운 JavaScript 인터뷰 질문 (0) | 2023.08.21 |
---|---|
[Vue.js] 간단한 Vue 기본 상식 시리즈 -2 Vue 라우터 Vue Router (0) | 2023.01.31 |
[Vue.js] 간단한 Vue 기본 상식 시리즈 -4 Vue 3 컴포지션 API (0) | 2023.01.15 |
[Vue.js] 간단한 Vue 기본 상식 시리즈 -3 Vue 3 프로젝트 라우팅 설정 (0) | 2023.01.13 |
[Vue.js] 간단한 Vue 기본 상식 시리즈 -2 Vue 3 프로젝트 시작하기 (0) | 2023.01.12 |