- javascript할당연산자변수저장위치
Javascript 변수타입별 '= 할당연산자' 차이와 저장공간
javascript는 변수 타입별로 primitive 변수는 stack에, object 변수는 heap 에 값을 저장한다. 이런 특징으로 할당연산 결과에 값 복사와 참조값(reference value) 복사와 같은 차이가 발생한다.
javascript에서 할당연산자의 특징을 간단히 하면,
JavaScript의
= (할당 연산자)에서 원시 타입(primitive)은 '값'을 복사하고, 객체타입(object)은 '참조값(메모리 포인터)'를 복사한다. typescript의 경우도 마찬가지다.(런타임에는 컴파일 이후 javascript로 변환 된 코드가 실행)
javascript 실행 환경에서 stack 과 heap
javascript가 실행될때 메모리 공간은 실행되는 코드가 있는 code(text segment), 로컬 함수 컨택스트가 저장되는 stack, 객체와 클로저가 들어가는 heap, 그리고 v8엔진에서 필요한 전역데이터 영역인 static/global 영역으로 나뉜다. 데이터 타입에 따라 stack 과 heap 에 저장된다.(최적화된 경우 제외)
원시타입은 stack에 참조타입은 heap에 저장
| 타입 | 특징 | 위치 |
|---|---|---|
| 원시 타입 (Primitive): number, string, boolean, null, undefined, symbol, bigint | 간단한 형태의 값. 값이 차지하는 메모리 크기가 작음. 한번 생성되면 값을 변경하지 않음(immutable) | stack |
| 참조 타입 (Object): Object, Array, Function, Date | 크기가 크고 구조와 형태가 다양하며, 크기가 변경될 수 있음. 객체 복사시 새로운 객체 만들기 부담스러움 | heap |
원시타입(primitive type)은 stack에 저장된 값을 할당
대부분의 경우 원시값은 stack 에 저장된다. 변수 할당 시 변수는 새 값을 가진다.(원시값은 immutable하여 내부 속성을 변경할 수 없음)
상세하게는 JS는 동적언어라서 각 변수는 stack에 변수슬롯을 가진다. 변수슬롯은 [type tag, value] 형태로 type tag은 number, string등 변수 타입 정보를 value는 실제 원시 값이다. 할당연산에서는 변수 슬롯이 새 값을 가진다.
let a = 10;
let b = 5;
b = a; // b 슬롯이 a 슬롯의 value(10)를 가리키도록 변경
b.x = a; // (오류) b는 primitive type이므로 immutable 위반객체타입(object)의 heap 포인터 참조값을 할당
객체타입(object)도 원시타입과 마찬가지로 stack에 변수슬롯(binding)을 가진다. 실제 객체값은 heap에 저장된다. 이때 stack의 변수 슬롯(binding)은 [type tag, value] 구조를 가지며 type tag은 object, value는 객체가 위치한 heap 주소(pointer)를 저장한다. 할당연산에서 좌측 변수는 우측변수와 동일한 heap 주소를 가리키게 되므로, 두 변수는 같은 객체 참조하게 된다. 즉, 참조값(reference)을 복사하는 결과를 가진다.
// 객체 생성
const obj1 = { name: "Alice", age: 25 };
// obj2에 obj1을 할당
const obj2 = obj1;
// obj2를 통해 객체 속성 변경
obj2.age = 30;
console.log(obj1.age); // 30
console.log(obj2.age); // 30Javascript 는 동적언어
동적언어는 변수 선언시 타입을 정의할 필요가 없어서 편리하다. 하지만 변수타입에 따라 할당이나 연산이 달라져야 한다. 이를 위해 JS 엔진은 [type tag, value] 형태의 변수슬롯을 가지고, type tag를 사용해 primitive인지 object인지 구분한다.
(끝)