들어가며
많은 기업들이 타입스크립트와 nest.js를 활용해서 서버 개발을 하곤 합니다. 취업을 하려면, 타입스크립트와 nest.js를 공부해서 실무를 익히는 것이 중요할 것입니다. 하지만 아직 자바스크립트의 기초도 없는 상태에서 타입스크립트와 nest.js를 공부하는 것이 맞을까 하는 생각이 들었습니다. 빠르게 기술변화를 적응하고, 러닝 커브를 줄이기 위해 빠르게 공부해야 하는 것도 맞겠지만, 그전에 언어의 기반이 되는 자바스크립트부터 제대로 알아야 하지 않을까 하는 생각이 들었습니다. 이 기회에 자바스크립트의 기본에 대해 정리해보고자 합니다.
변수 선언과 데이터 할당
변수를 선언할 때, 메모리 영역에서 어떤 작업을 수행하는지 살펴보겠습니다.
var a;
주소 | ... | 1002 | 1003 | 1004 | 1005 | ... |
데이터 | 이름: a 값 : |
var a라는 명령을 받은 컴퓨터는 메모리에서 비어있는 공간 하나를 확보합니다. 위의 표에서 임의로 1003번으로 정했습니다. 이 공간의 이름(식별자)을 a라고 지정합니다. 여기까지가 변수 선언 과정입니다. 이후에 사용자가 a에 접근하고자 하면 컴퓨터는 메모리에서 a라는 이름을 가진 주소를 검색해 해당 공간에 담긴 데이터를 반환할 것입니다. 그렇다면, 변수에 값을 할당하는 과정은 어떻게 이루어질까요? 이에 대해 알아보겠습니다.
데이터 할당
var a; // 변수 a 선언
a = 'abc'; // 변수 a에 데이터 할당
var a = 'abc'; // 변수 선언과 할당을 한 문장으로 표현
선언과 할당을 나누어서 하거나, 동시에 하거나 자바스크립트 엔진은 같은 동작을 수행합니다. 메모리에서 비어있는 공간을 확보하고 그 공간의 이름을 설정하는 선언 과정은 앞서 살펴본 것과 같습니다. 이 부분에서는 할당 과정에 대해 살펴보겠습니다.
만약 a라는 이름의 주소를 검색해서, 그곳의 값에 문자열 'abc'를 할당하면 선언과 할당이 모두 끝날 것입니다. 하지만, 실제로 해당 위치에 문자열 'abc'를 직접 저장하지 않습니다. 데이터를 저장하기 위한 별도의 메모리 공간을 다시 확보해서 문자열 'abc'를 저장하고, 그 주소를 변수 영역에 저장하는 식으로 이뤄집니다.
아래의 설명부터는 데이터의 성격에 따라 '변수 영역', '데이터 영역'으로 구분하겠습니다. 이를 구분해서 데이터 할당의 전체 흐름을 살펴보면 다음과 같습니다.
변수 영역
주소 | ... | 1002 | 1003 | 1004 | 1005 | ... |
데이터 | 이름 : a 값 : @5004 |
데이터 영역
주소 | ... | 5002 | 5003 | 5004 | 5005 | ... |
데이터 | 'abc' |
과정
1. 변수 영역에 빈 공간(@1003)을 확보한다.
2. 확보한 공간의 식별자를 a로 지정한다.
3. 데이터 영역의 빈 공간(@5004)에 문자열 'abc'를 저장한다.
4. 변수 영역에서 a라는 식별자를 검색한다(@1003).
5. 앞서 저장한 문자열의 주소(@5004)를 @1003의 공간에 대입한다.
위에서 살펴본 것처럼, 왜 변수 영역에 값을 바로 넣는 것이 아니라, 굳이 번거롭게 데이터 영역에 데이터를 넣고, 변수 영역에 데이터 영역의 위치를 추가하는 것일까요? 이는 데이터 변환을 자유롭게 할 수 있게 함과 동시에 메모리를 더욱 효율적으로 관리하기 위한 고민의 결과입니다. 앞에서 자바와 C언어와 다르게 자바스크립트는 숫자형 데이터에 대해 64비트(8바이트)의 공간을 확보한다고 했습니다. 하지만 문자열은 특별히 정해진 규격이 없습니다. 한 글자마다 영어는 1바이트, 한글은 2바이트 등으로 각각 필요한 메모리 용량이 가변적입니다.
이때 미리 확보한 공간 내에서만 데이터 변환을 할 수 있다면, 변환한 데이터를 다시 저장하기 위해서는 '확보된 공간을 변환된 데이터 크기에 맞게 늘리는 작업'이 선행돼야 할 겁니다. 해당 공간이 메모리 상의 가장 마지막에 있었다면 뒤쪽으로 늘리기만 하면 되니까 어렵지 않겠지만 중간에 있는 데이터를 늘려야 하는 상황이라면 해당 공간보다 뒤에 저장된 데이터들을 전부 뒤로 옮기고, 이동시킨 주소를 각 식별자에 다시 연결하는 작업을 해야 합니다. 결국 효율적으로 문자열 데이터의 변환을 처리하려면 변수와 데이터를 별도의 공간에 나누어 저장하는 것이 최적입니다.
만약 문자열 'abc'의 마지막에 'def'를 추가하라고 하면 컴퓨터는 앞서 'abc'가 저장된 공간에 'abcdef'를 할당하는 대신 'abcdef'라는 문자열을 새로 만들어 별도의 공간에 저장하고, 그 주소를 변수 공간에 연결합니다. 반대로 'abc'의 마지막 'c'를 제거하라고 해도 새로 만듭니다. 기존 문자열에 어떤 변환을 가하든 상관없이 무조건 새로 만들어 별도의 공간에 저장합니다.
변수 영역
주소 | ... | 1002 | 1003 | 1004 | 1005 | ... |
데이터 | 이름 : a 값 : @5005 |
데이터 영역
주소 | ... | 5002 | 5003 | 5004 | 5005 | ... |
데이터 | 'abc' | 'abcdef' |
이때 기존 5004 데이터는 자신의 주소를 저장하는 변수가 하나도 없게 되면 가비지 컬렉터의 수거 대상이 됩니다.
다른 예로 500개의 변수를 생성해서 모든 변수에 숫자 5를 할당하는 상황을 생각해 봅시다. 각 변수를 별개로 인식하려면 500개의 변수 공간을 확보하는 것은 불가피합니다. 그런데 각 변수 공간마다 매번 숫자 5를 할당하는 상황을 생각해 봅시다. 각 변수를 별개로 인식하려면 500개의 변수 공간을 확보하는 것은 불가피합니다. 그런데 각 변수 공간마다 매번 숫자 5를 할당하려고 하면 숫자형은 8바이트가 필요하다고 했으니까 총 4000(500*8) 바이트를 써야 할 것입니다. 그 대신 5를 별도의 공간에 한 번만 저장하고 해당 주소만 입력한다면 어떨까요? 예를 들어, 주소 공간의 크기가 2바이트라고 한다면 1008(500 * 2 + 8) 바이트만 이용하면 됩니다. 이처럼 변수 영역과 데이터 영역을 분리하면 중복된 데이터에 대한 처리 효율이 높아집니다.
이 공부를 통해 변수가 선언되고, 변수에 값이 할당될 때, 메모리는 어떻게 동작하는지에 대해 간략하게 배웠습니다. 그렇다면 다음엔 기본형 데이터와 참조형 데이터가 어떤 차이가 있고, 메모리 동작에는 어떤 차이가 있는지 알아보겠습니다.
마치며
자바스크립트의 기본에 대해 공부하면서, 기본도 정확하게 알지 못하고, 앞으로 나아가려 했구나 하는 생각이 들었습니다. 기초이기에 지금 공부하는 내용을 더 잘 이해해야겠다고 생각했습니다. 기본에 충실할 수 있는 개발자가 되고 싶습니다.
출처
'JavaScript > 코어 자바스크립트' 카테고리의 다른 글
[자바스크립트] 실행 컨텍스트란? (feat 코어 자바스크립트) (1) | 2021.09.24 |
---|---|
[자바스크립트] undefined와 null (feat 코어 자바스크립트) (0) | 2021.09.16 |
[자바스크립트] 불변 객체 (feat 코어 자바스크립트) (0) | 2021.09.13 |
[자바스크립트] 기본형 데이터와 참조형 데이터 (feat 코어 자바스크립트) (0) | 2021.09.04 |
[자바스크립트] 데이터 타입 종류와 배경지식 (feat 코어 자바스크립트) (0) | 2021.09.01 |