본문 바로가기
Frontend/Javascript

[JavaScript] 불변성(Immutability) vs 가변성(Mutability)

by hyeok1235 2023. 6. 24.

불변성(Immutability)과 가변성(Mutability)는 다른 언어에서도 사용되는 개념이지만, 이번 글에서는 자바스크립트에서 불변성과 가변성의 개념에 대해서 설명하겠습니다. 

 

변경이 불가능한 데이터 타입은 원시 타입(Primitive Type)이라고 합니다. 원시 타입의 유형으로는 불리언, 문자열, 수, null, undefined, Symbol이 있습니다.. 

 

원시 타입의 데이터를 변수에 할당한다는 것은, 값이 저장되어 있는 메모리의 주소를 변수가 직접적으로 가리키게 하는 것입니다. 원시 타입이 불변하다는 것은, 원시 타입의 데이터가 저장되어 있는 메모리 영역에서의 변경이 불가하다는 뜻입니다. 따라서 만약 원시 타입이 저장되어 있는 변수의 값을 변경하고자 한다면, 기존의 값이 저장되어 있는 메모리 영역의 변경이 아니라 새로운 메모리 영역이 사용됩니다. 

 

let ex_str = "Hello?";
ex_str[5] = "!"; // TypeError
ex_str = "Hello!"

앞서 주어진 코드를 살펴보면 2번째 줄에서 에러가 발생하게 됩니다.(느슨한 모드에서는 에러가 발생하지 않지만, 값의 변경이 일어나지 않습니다.) "Hello?"가 저장되어 있는 메모리 공간의 변경을 시도했기 때문입니다. 수정을 하기 위해서는 아예 새로운 값을 할당해야만 하는 것을 알 수 있습니다. 

 

원시 타입이 불변성은 크게 2가지의 장점을 가지고 있습니다. 

① 메모리 사용을 줄일 수 있습니다. 만약 똑같은 값이 메모리 공간에 중복으로 저장되면, 불필요한 메모리 사용이 발생하게 됩니다. 기존에 존재하는 메모리 공간을 참조함으로써 메모리 공간을 효율적으로 사용할 수 있습니다. 

② 다중 스레드 작업에서 데이터의 오염을 걱정하지 않아도 됩니다. 원시 타입이 저장된 메모리 공간은 변경되지 않기 때문에 여러 스레드가 서로 간섭하지 않고 동일한 객체 참조를 가능하게 합니다. 


원시 타입으로 구분되지 않는 데이터 타입은 모두 객체 타입(Object Type)이라고 부르며 변경이 가능합니다. 참조 타입(Reference Type)이라고 부르기도 하며, 대표적인 예시로는 배열, 함수, 객체 등이 있습니다.

 

참조 타입의 데이터를 변수에 할당하면 간접적으로 데이터에 대한 참조가 변수에 저장됩니다. 따라서 만약 참조 타입이 저장되어 있는 변수의 값을 변경하고자 한다면, 새로운 값이 만들어지지 않고 변수의 값 자체가 변경이 됩니다. 

 

let ex_arr = ['foo'];
ex_arr.push('bar');
console.log(ex_arr); // ['foo', 'bar']

앞서 주어진 코드를 살펴보면 push() 메소드를 통해 변수가 저장된 값을 변경하는 것에 성공하였습니다. 새로운 값을 할당하는 것이 아닌, 원본 값 자체를 변경한 것임을 알 수 있습니다. 

 

let x = {
    size: 21
};
let y = x;
y.size = 25;
console.log(x.size); // 25

yx가 가리키고 있는 객체의 주소와 동일하기 때문에, y가 가리키고 있는 객체의 size 속성을 변경하였음에도 불구하고 x도 값이 변경되게 됩니다. 이는 참조 타입의 데이터가 할당된 변수들은 직접적으로 데이터에 접근하는 것이 아니라, 데이터에 대한 간접적인 참조를 하고 있기 때문입니다. 

 

※ const 키워드를 사용하여 객체를 선언했어도, 객체의 속성값을 변경할 수 있는 이유도 객체가 참조 타입의 데이터이기 때문입니다. const로 선언된 변수는 불변하지만, 변수가 참조하고 있는 값은 가변하기 때문에 객체의 속성값을 재할당할 수 있습니다. 

728x90
반응형