[JavaScript] var, let, const
[JavaScript] var, let, const
JavaScript에서 변수를 선언하는 방법은 var, let, const가 있다.
요즘은 대부분 let과 const를 사용하고, var는 레거시 코드에서 주로 만난다.
이 글은 아래 3가지만 확실하게 정리하는 게 목표이다.
- 스코프(scope): 변수가 “어디까지” 보이는가?
- 재선언/재할당: 같은 이름으로 다시 선언 가능한가? 값 변경 가능한가?
- 호이스팅(hoisting): 선언이 “어떻게” 끌어올려지는가?
1) 스코프: 함수 스코프(var) vs 블록 스코프(let/const)
var는 함수 스코프
var는 if, for 같은 블록 {}을 무시하고, 함수 단위로만 영역이 나뉜다.
1
2
3
4
5
6
7
function demo() {
if (true) {
var x = 1;
}
console.log(x); // 1 (블록 밖인데도 접근 가능)
}
demo();
let/const는 블록 스코프
let, const는 블록 {} 기준으로 영역이 나뉜다.
1
2
3
4
5
6
7
8
9
function demo() {
if (true) {
let y = 2;
const z = 3;
}
console.log(y); // ReferenceError
console.log(z); // ReferenceError
}
demo();
2) 재선언 / 재할당 차이
var: 재선언 OK, 재할당 OK
1
2
3
var a = 1;
var a = 2; // 재선언 가능
a = 3; // 재할당 가능
let: 재선언 NO, 재할당 OK
1
2
3
let b = 1;
// let b = 2; // SyntaxError: Identifier 'b' has already been declared
b = 2; // 재할당 가능
const: 재선언 NO, 재할당 NO
1
2
const c = 1;
// c = 2; // TypeError: Assignment to constant variable.
다만 const로 선언한 객체/배열은 내부 값 변경이 가능하다.
(변수 자체의 “참조”가 고정되는 것이지, 내부가 완전 불변은 아님)
1
2
const obj = { count: 0 };
obj.count = 1; // OK (객체 내부 값 변경)
하지만 참조 자체를 바꾸는 건 불가능하다.
1
2
const obj = { count: 0 };
// obj = { count: 1 }; // TypeError
3) 호이스팅: “된다/안된다”가 아니라 “어떻게 되냐”가 핵심
var 호이스팅: 선언이 끌어올려지고, 초기값은 undefined
1
2
3
console.log(v); // undefined
var v = 10;
console.log(v); // 10
위 코드는 내부적으로 아래처럼 동작한다(개념적으로).
1
2
3
4
var v;
console.log(v); // undefined
v = 10;
console.log(v); // 10
그래서 var는 의도치 않은 버그를 만들기 쉽다.
let/const 호이스팅: 선언은 끌어올려지지만, TDZ 때문에 접근하면 에러
1
2
3
4
5
console.log(l); // ReferenceError
let l = 10;
console.log(k); // ReferenceError
const k = 10;
TDZ(Temporal Dead Zone): 선언은 되었지만 초기화되기 전까지 접근하면 에러가 나는 구간
한눈에 비교표
| 구분 | 스코프 | 재선언 | 재할당 | 호이스팅 | 추천도 |
|---|---|---|---|---|---|
var | 함수 스코프 | 가능 | 가능 | 가능(초기값 undefined) | 낮음 |
let | 블록 스코프 | 불가 | 가능 | 가능(TDZ) | 높음 |
const | 블록 스코프 | 불가 | 불가(참조 고정) | 가능(TDZ) | 매우 높음 |
마무리 정리
var : 함수 스코프 + undefined 호이스팅 때문에 예측이 어려워질 수 있음
let : 블록 스코프 + 재할당 가능
const : 블록 스코프 + 재할당 불가(가장 기본으로 추천)
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.