원시 값과 불변성

(Primitive Values and their Immutability in JavaScript)

Inpyo Lee
4 min readMar 14, 2022

자바스크립트는 숫자, 문자열, 불리언(true or false), null, undefined, 심벌, 그리고 객체 타입의 총 7가지 데이터 타입을 제공하며, 이는 다시 원시 타입(primitive type)객체 타입(object type/reference type)으로 구분된다. 객체 타입의 데이터가 “변경 가능한 값(mutable value)”인 반면, 원시 타입 데이터는 “변경 불가능한 값(immutable value)”이다. 여기서는 이러한 변경 불가능한 값으로서의 원시 값의 특징에 대해 살펴볼 것이다.

변경 불가능한 값

“원시 타입의 값, 즉 원시 값은 변경 불가능한 값이다.” 이는 데이터가 저장된 메모리의 주소를 식별하는 식별자, 즉 변수에 대한 진술이 아니라는 점에 유의하자. 값의 재할당에 대해 생각해보면 변수가 참조하는 메모리 주소를 변경하고 그 메모리에 새로운 값을 할당함으로써 변수의 값을 변경, 엄밀히 말하자면 교체할 수 있다는 점은 분명하기 때문이다. 이런 점에서 “변수의 상대 개념인 상수는 재할당이 금지된 변수”를 칭하는 것일 뿐이지, 실제 저장된 원시 값이 변경될 수 없음을 의미하는 것은 아니다.

한편 할당/재할당을 명령할 때 “변수가 참조하던 메모리 주소가 변경”되는 것은 곧 “변수에 할당된 원시 값이 변경 불가능한 값이기 때문이다.” 원시 값 자체가 변경 가능한 값이라면 변수가 다른 메모리 주소를 참조할 필요 없이 해당 메모리에 저장된 값만 계속 변경함으로써 재할당을 수행할 수 있을 것이고, 불필요한 쓰레기 값(garbage values)도 생성되지 않을 것이다. “하지만 원시 값은 변경 불가능한 값이기 때문에 값을 직접 변경할 수 없다. 따라서 변수 값을 변경하기 위해 원시 값을 재할당하면 새로운 메모리 공간을 확보하고 재할당한 값을 저장한 후, 변수가 참조하던 메모리 공간의 주소를 변경한다. 값의 이러한 특성을 불변성(immutability)이라 한다.”

let str = 'orange';console.log(str[0]); // o (can reach to certains char using index values)str[0] = 'O';console.log(str); // orange (the first character is not changed.)

문자열은 유사 배열 객체(array-like object)[1]이다. 그렇기에 위처럼 인덱스 값을 통해 특정 순번의 문자에 접근할 수 있다. 하지만 문자열은 변경 가능한 값인 객체가 아닌, 변경 불가능한 원시 값이다. 따라서 위의 str[0] = ‘O’처럼 “이미 생성된 문자열의 일부 문자를 변경해도 반영되지 않는다.”

값에 의한 전달

let num = 50;
let copy = num;
console.log(num); // 50
console.log(copy); // 50
num = 100;console.log(num); // 100
console.log(copy); // 50 (not changed!)

위에서 변수 num에는 원시 값 50을 할당하였고, 변수 copy에는 변수명 num을 할당하였다. 이때 변수 num에 100을 재할당하더라도 변수 copy는 여전히 50을 가리킨다. 이는 “변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달된다”는 점을 보여주는데, “이를 값에 의한 전달이라 한다.” 즉 num에 값을 재할당하기 이전에 num과 copy가 갖는 원시 값 50은 서로 동등하지만 각자 “다른 메모리 공간에 저장된[2] 별개의 값이다.” 따라서 변수 num이나 copy의 값을 몇 번 변경하든 이는 상대의 값에 “어떠한 영향도 주지 않는다.”

[1] 마치 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티를 갖는 객체를 말한다. 일례로 문자열은 마치 배열처럼 인덱스를 통해 각 문자에 접근할 수 있으며, for 문으로 순회할 수도 있다.

[2] 실제로 자바스크립트 엔진이 두 변수가 서로 다른 메모리 공간을 가리키도록 작동하지는 않을 수도 있다. 가령 파이썬은 변수 할당 시점에는 두 변수가 같은 메모리 공간의 같은 원시 값을 참조하다가 한 쪽에 재할당이 이뤄졌을 때 비로소 그 변수가 다른 메모리 공간의 다른 값을 참조하도록 작동한다.

이웅모, 모던 자바스크립트 Deep Dive(위키북스, 2020).

--

--