
| ES6 전 | ES6 후 |
|---|---|
| • 숫자(number) • 문자열(string) • 불리언(boolean) • null, undefined | • 숫자(number) • 문자열(string) • 불리언(boolean) • null, undefined • 심볼(symbol) ← 🆕 |
| ES6 전 | ES6 후 |
|---|---|
| • 객체(object) • 배열(Array) • 함수(function) • 날짜(date) • 정규표현식(regexp) | • 객체(object) • 배열(Array) • 함수(function) • 날짜(date) • 정규표현식(regexp) • Map ← 🆕 • WeakMap ← 🆕 • Set ← 🆕 • WeakSet ← 🆕 |
const sym1 = Symbol('description');
const sym2 = Symbol('description');
console.log(sym1 === sym2); // false - 항상 유일함
const map = new Map();
map.set('string', 'value1');
map.set(42, 'value2');
map.set(true, 'value3');
const wm = new WeakMap();
let obj = {};
wm.set(obj, 'some value');
obj = null; // 객체가 GC될 수 있음
const set = new Set([1, 2, 2, 3, 3]);
console.log(set); // Set {1, 2, 3}
const ws = new WeakSet();
let obj1 = {};
ws.add(obj1);
obj1 = null; // 객체가 GC될 수 있음
🚨 중요한 오해 바로잡기
기본형은 할당이나 연산 시 복제되고 참조형은 참조 된다고 알려져 있다.
하지만, 엄밀히 말하면 둘 모두 복제를 하긴 한다!
차이점:
비트 단위로 위치를 확인하는 것은 매우 비효율적이므로 몇 개씩 묶어 하나의 단위로 여기면 표현할 수 있는 값도 늘어나면서 동시에 검색 시간을 줄일 수 있다.
| 정적 타입 언어 (C, C++, Java) | JavaScript |
|---|---|
| • 메모리 낭비 최소화를 위해 데이터 타입별로 할당 메모리 영역을 정해놓음 • 2바이트, 4바이트 등으로 구분 • 사용자가 직접 형변환 필요 | • 메모리 관리 압박에서 자유로움 • 메모리 공간을 넉넉하게 할당 • 숫자는 모두 64비트(8바이트) 확보 |
| 구분 | 정의 | 설명 |
|---|---|---|
| 변수 | '변할 수 있는 수' | 컴퓨터 용어로는 변할 수 있는 무언가(데이터)를 의미 숫자, 문자열, 객체, 배열 모두 데이터 |
| 식별자 | 변수명 | 어떤 데이터를 식별하는 데 사용하는 이름 |
// 1. 변수 선언
var a;
// 2. 데이터 할당
a = 'abc';
// 3. 선언과 할당을 동시에
var a = 'abc';
| 변수영역 | 데이터 영역 |
|---|---|
| 주소: 1002 | 주소: 5002 |
| 데이터: a | 데이터: 'abc' |
| 값: @5002 |
굳이 변수영역에 직접 데이터를 저장하지 않고 데이터영역에 저장하는 이유:
| 구분 | 대상 | 설명 |
|---|---|---|
| 변수와 상수 | 변수 영역 메모리 | 한 번 데이터 할당이 이뤄진 변수 공간에 다른 데이터를 재할당할 수 있는지 여부 |
| 불변값과 가변값 | 데이터 영역 메모리 | 데이터 영역의 값 자체를 변경할 수 있는지 여부 |
var obj1 = {
a: 1,
b: 'bbb'
};
| 변수영역 |
|---|
| 주소: 1001 |
| 데이터: obj1 |
| 값: @5001 |
| 데이터 영역 |
|---|
| 주소: 5001 |
| 데이터: @7103 ~ ? |
| 객체 변수 영역 |
|---|
| 주소: 7103 - 데이터: a, 값: @5003 |
| 주소: 7104 - 데이터: b, 값: @5004 |
| 데이터 영역 |
|---|
| 주소: 5003 - 데이터: 1 |
| 주소: 5004 - 데이터: 'bbb' |
참조형 데이터가 가변값이 될 수 있는 이유는 변수를 재할당하는 과정에서 볼 수 있다.
만약 obj1.a = 2;라는 코드를 실행한다면:
1. 데이터 영역에 숫자 2가 있는지 검색하고 없다면 새로운 데이터 영역(예: 5005)에 할당한다.
2. 객체 변수 영역인 주소값 7103인 공간에 주소값 5005를 저장한다.
3. 변수 obj1이 가리키고 있는 주소(5001)는 변화하지 않는다.
4. 데이터영역은 불변이지만, 객체의 변수 영역에는 다른 값을 얼마든지 대입할 수 있기 때문에 참조형 데이터는 가변값이다.
var obj1 = {
a: 1,
arr: [3, 4, 5]
};
| 변수영역 |
|---|
| 주소: 1001 |
| 데이터: obj1 |
| 값: @5001 |
| 데이터 영역 |
|---|
| 주소: 5001 - 데이터: @7103 ~ ? |
| 주소: 5002 - 데이터: 'aba' |
| 주소: 5003 - 데이터: @8103 ~ ? (배열 arr의 변수영역 주소) |
| 주소: 5004 - 데이터: 'bbb' |
| 주소: 5005 - 데이터: 5 |
| 객체 변수 영역 |
|---|
| 주소: 7103 - 데이터: a, 값: @5003 |
| 주소: 7104 - 데이터: arr, 값: @5003 |
| 배열 arr 변수 영역 |
|---|
| 주소: 8103 - 데이터: 0, 값: @5002 |
| 주소: 8104 - 데이터: 1, 값: @5004 |
| 주소: 8105 - 데이터: 2, 값: @5005 |
중첩된 참조형 데이터의 프로퍼티 할당은 객체의 변수 영역을 따로 선언했던 것처럼 해당하는 배열이나 데이터에 대한 변수 영역을 따로 선언하여 주소값을 할당하는 방식으로 사용한다.
만약 obj1.arr = 'str';이라는 코드를 실행하여 재할당하면:
1. 문자열 'str'이 없기 때문에 데이터영역에 새로운 주소로 데이터를 할당한다.
2. 객체의 변수영역이 새로운 주소를 참조하게 된다.
3. 더 이상 참조하지 않는 데이터는 가비지 컬렉터의 대상이 된다.
var a = 10;
var b = a;