변수에는 메모리의 주소가 저장되어 있다. 그러니까, 특정 값이 저장되어 있는 것이 아닌, 특정값이 저장되어 있는 메모리의 주소를 가지고 있는 것이다. 변수에 값이 재할당될때 해당 값이 스택에 존재하면 그 스택 주소로 할당된다는 내용을 본 것 같은데, 값이 같더라도 다른 메모리 주소에 값이 저장되는 줄 알았는데 그게 아니어서 좀 더 정확하게 공부해서 정리해보려고 한다.
변수의 종류에 따라 저장되는 위치가 다르다.
메모리는 4개의 영역이 있고, 전역변수, 지역변수, 코드, 동적할 할당에 따라 저장되는 위치가 다르다.
자바스크립트 엔진은 힙영역과 콜스택을 사용한다.
콜스택
원시 타입 데이터가 저장된다.
변수에 저장되는 것 : 콜스택의 주소
메모리 힙(heap 영역)
참조 타입 데이터가 저장된다. (배열, 객체, 함수 등)
메모리 힙에 저장되는 것 : 값
콜스택에 저장되는 것 : 값이 저장된 힙의 주소
변수에 저장되는 것 : 콜스택 주소
변수 종류별 할당과 재할당 과정
1. 원시 타입
1.1 원시 타입의 할당 과정
let a = 10;
- 위에서 언급했듯, 원시타입은 콜스택에 저장된다.
- 원시타입의 값을 콜스택에 저장하고, 해당 메모리 주소를 변수에 저장한다.
1.2 원시 타입의 재할당 과정(존재하는 값으로 할당)
let a = 10;
let b = 20;
a = 20;
- a, b는 원시타입이 할당하는 과정을 그대로 진행했기 때문에 10과 20이 콜스택에 저장되어 있다.
- a의 값을 20으로 재할당한다면, 10이 저장되어 있는 메모리에서 20으로 변경되거나 새로운 메모리 공간을 마련해 20을 저장하는 것이 아닌, 기존에 b가 참조하고 있는 20이 저장되어있는 메모리의 주소값이 a에 저장되게 된다.
- 따라서 a와 b가 저장하고 있는 주솟값은 같다.
1.3 원시 타입의 재할당 과정(새로운 값으로 할당)
a = 30;
- a에 30을 재할당 한다면, 콜스택에 30은 저장되어 있지 않기 때문에 새로운 메모리를 확보해서 30을 저장하고 a에 해당 콜스택의 주소값을 저장한다.
1.4 사용하지 않는 메모리는 어떻게 될까?
- a가 처음에 할당했던 10은 이제 더이상 사용되고 있지 않다.
- 가비지 컬렉더는 더이상 참조되지 않는 데이터 10을 삭제한다.
2. 참조 타입
2.1 참조 타입의 할당 과정
const arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
- 힙영역에는 원시 타입이 아닌 타입들이 저장된다. 동적인 타입들은 갑자기 데이터가 커지거나 작아질 수 있는데 이러한 배열이나 객체들을 힙영역에 저장할 수 있다는 것이 핵심이다.
- 그렇다고 콜스택을 사용하지 않는 것이 아니다.
- 배열의 값들은 힙 영역에 저장되고 힙영역의 주소값이 콜스택에 저장되며 콜스택의 주소값이 변수에 저장되는 것이다.
2.2 참조 타입의 재할당 과정
const arr = [1, 2, 3];
arr.push(4); // [1, 2, 3, 4]
arr.push(5); // [1, 2, 3, 4, 5]
arr.pop(); // [1, 2, 3, 4]
- 참조 타입의 변수에는 콜스택의 주솟값이 들어가있기 때문에 const를 사용하여 선언해도 참조 값의 요소를 추가하거나 제거하는 것이 가능하다.
const arr1 = [1, 2, 3];
arr1 = [4, 5, 6]; // TypeError: Assignment to constant variable.
let arr2 = [1, 2, 3];
arr2 = [4, 5, 6]; // 정상적으로 재할당 됨
- 하지만 위 코드와 같이 const로 선언된 참조 타입의 변수는 콜스택의 메모리 주소를 바꿀 수 없다.
2.3 자바스크립트 스타일 가이드
위 참조 타입의 예시와 같이 참조타입의 경우는 재할당이 이루어져야하는 경우가 아니라면 const로 선언하는 것이 좋다.
구글에서 자바스크립트 스타일 가이드로 아래와 같은 내용이 있는데 왜 그런지 이유와 함께 적고 마무리하겠다.
- 모든 지역 변수를 const나 let으로 선언해라.
- 변수를 재할당하지 않는 한, 기본적으로 const를 사용해라.
- var 키워드는 절대 사용하지 마라.
이유
- 미래의 버그를 사전에 방지할 수 있다.
- const를 통해 선언된 변수는 반드시 선언과 동시에 초기화가 되어야 하며, 이를 통해 개발자는 스코프적인 측면에서 더욱 신중하게 변수를 배치해야 함을 강요받게 된다. 이는 궁극적으로 더 나은 메모리 관리 및 성능으로 이어지게 된다.
- 단지 코드를 보는 것만으로도 어떤 변수가 변경 불가능하고, 또 어떤 변수가 재할당이 가능한지 의사소통할 수 있다.
참조
https://okky.kr/questions/1314322
OKKY - 자바스크립트 전역변수는 어디 영역에 저장되나요?(call stack, heap)
기본적인 컴퓨터 지식으로 메모리는 4개의 영역이 있고 전역변수, 지역변수, 코드, 동적할 할당에 따라 저장되는 위치가 다릅니다.그런데 자바스크립트 엔진은 "Call Stack" 과 "Heap" 두 가지 영역을
okky.kr
https://velog.io/@pppp0722/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0-
%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0
메모리 구조 이해하기
메모리란? 작업을 처리하기 위한 기억 장치로 물리(메인) 메모리(RAM), 가상 메모리(SSD, HDD의 swap 영역)가 존재한다. 가상 메모리 : 필요한 내용만 물리 메모리에 올려 메모리를 관리하는 기법으로
velog.io
https://gritdonghee.notion.site/let-const-9fa10728553644fb88ab61b415c129e9
콜스택/메모리힙에 저장되는 데이터 타입와 재할당 과정(let/const) | Notion
https://charming-kyu.tistory.com/19
gritdonghee.notion.site
https://charming-kyu.tistory.com/19
[javascript] 콜스택/메모리힙 구조, 데이터 저장/참조 원리
콜 스택, 메모리 힙이란? 자바스크립트 엔진은 Memory Heap 과 Call Stack 으로 구성되어 있습니다. 가장 유명한 것이 구글의 V8 Engine입니다. 자바스크립트는 단일 스레드 (sigle thread) 프로그래밍 언어인
charming-kyu.tistory.com
'FE > JavaScript' 카테고리의 다른 글
[JavaScript] 실행 컨텍스트(execution context) (0) | 2024.07.31 |
---|---|
[JavaScript] 자바스크립트 문자열 반복 메소드 repeat() (0) | 2024.04.04 |
[JavaScript] 자바스크립트 최대/최소 정수값 MAX_SAFE_INTEGER/MIN_SAFE_INTEGER (0) | 2024.04.04 |
[JavaScript] 자바스크립트 정수인지 확인하는 Number.isInteger() 메소드 (0) | 2024.04.01 |
[JavaScript] 자바스크립트 대소문자 변경하기 toUpperCase(), toLowerCase() (0) | 2024.03.31 |