JavaScript: var, let, const 차이점 정리 (변수 호이스팅 포함)
1. 중복 선언 가능 여부
키워드 | 중복 선언 가능 여부 |
---|---|
| ✅ 가능 |
| ❌ 불가능 (SyntaxError 발생) |
| ❌ 불가능 (SyntaxError 발생) |
var
는 동일한 스코프 내에서 같은 이름으로 여러 번 선언해도 에러 없이 동작한다.let
과const
는 같은 이름으로 중복 선언할 수 없다.
2. 재할당 가능 여부
키워드 | 재할당 가능 여부 |
---|---|
| ✅ 가능 |
| ✅ 가능 |
| ❌ 불가능 (TypeError 발생) |
설명:
- var, let : 값의 재할당이 가능한 변수다. 변수 선언 및 초기화 이후에 반복해서 다른 값을 재할당 할 수 있다.
- const : 상수(constant) 선언에 사용되며, 초기화 이후 값 변경이 불가하다. 단, 객체나 배열은 내부 속성/요소 변경은 가능하다.
- var 또는 let과 달리, const 선언에서는 반드시 값을 선언과 동시에 정의해야 한다
- * 재할당이 필요없는 경우, const를 사용해 불필요한 변수의 재사용을 방지하고, 재할당이 필요한 경우 let을 사용하자.
const obj = { a: 1 };
obj.a = 2; // 가능
3. 스코프(Scope)
키워드 | 스코프 종류 |
---|---|
| 함수 스코프 (Function Scope) |
| 블록 스코프 (Block Scope) |
| 블록 스코프 (Block Scope) |
var
는 함수 내부에서만 지역 변수로 인식된다.
→ {}
블록 내에서 선언해도 함수 바깥에서도 접근 가능하다.
let
,const
는 블록 내에서만 유효한 변수이다. 즉, 블럭이 끝나고 나오면 값이 변수에 덮어쓰기 되지 않는다.
var
: 함수 레벨 스코프(function-level scope)
var
는 함수 내부에 선언된 변수만 지역변수로 한정하며, 나머지는 모두 전역변수로 간주한다.- 자바스크립트애서는 if문, for문, while문, try/catch 문 등의 코드 블럭{ ... } 내부에서
var
로 선언된 변수를 전역 변수로 간주한다. - 그래서 블럭 외부에서도 어디에서나 참조할 수 있다.
let
, const
: 블록 레벨 스코프(block-level scope)
let
,const
는 함수 내부는 물론, if문이나 for문 등의 코드 블럭{ ... } 에서 선언된 변수도 지역변수로 취급한다.- 당연히 함수 내부에서 선언된 변수도 외부에서 참조할 수 없다.
if (true) {
var a = 1;
let b = 2;
const c = 3;
}
console.log(a); // ✅ 1
console.log(b); // ❌ ReferenceError
console.log(c); // ❌ ReferenceError
4. 변수 호이스팅(Variable Hoisting)
변수 호이스팅이란?
자바스크립트는 코드를 실행하기 전에 한 번 코드를 스캔하면서 변수 선언을 끌어올리는 동작을 수행한다. 이 과정을 변수 호이스팅(Variable Hoisting)이라고 한다. 즉, 변수가 선언되기 전에 사용 가능한 것처럼 보이는 현상이다,
var
의 호이스팅
console.log(a); // undefined
var a = 10;
console.log(a); // 10
내부 동작
var a = undefined;
console.log(a); // undefined
a = 10;
console.log(a); // 10
var
는 호이스팅 시 선언과 동시에 undefined로 초기화됨.- 그래서 에러 없이
undefined
가 출력된다.
let
/ const
의 호이스팅
console.log(a); // ❌ ReferenceError
let a = 10;
let
,const
도 호이스팅은 되지만, 초기화가 이루어지지 않은 "TDZ(Temporal Dead Zone)" 상태가 존재함.- **TDZ(일시적 사각지대)**에서는 변수를 참조할 수 없어 에러 발생.
TDZ (Temporal Dead Zone)
let a = 10;
if (true) {
console.log(a); // ❌ ReferenceError
let a = 20;
}
if
블록 안에서a
를 새로 선언하려 하면,
그 블록 안의a
는 전역의a
를 가리키지 않고 새로운 지역 변수가 됨.- 하지만 초기화 이전 시점에서
a
를 참조했기 때문에 에러 발생.
키워드 | 호이스팅 여부 | 초기화 상태 |
---|---|---|
| ✅ 선언과 초기화(undefined) | 초기화됨 |
| ✅ 선언만 됨 (TDZ 존재) | 초기화 안됨 |
| ✅ 선언만 됨 (TDZ 존재) | 초기화 안됨 |
var
는 호이스팅 시 선언 + 초기화(undefined) 되므로 에러 없이undefined
출력한다.let
,const
는 **호이스팅은 되지만 TDZ(Temporal Dead Zone)**에 걸려 초기화 전에는 접근 불가하다.
console.log(a); // undefined
var a = 10;
console.log(b); // ReferenceError
let b = 10;
📎 TDZ란?
let
/const
변수가 선언되었지만 초기화되지 않은 시점에서 접근하면 발생하는 오류 구간
5. 전역 객체 등록 여부
키워드 | 전역 객체(window 등)에 등록 여부 |
---|---|
| ✅ 등록됨 ( |
| ❌ 등록 안 됨 |
| ❌ 등록 안 됨 |
설명:
브라우저 환경에서는 var
로 선언한 전역 변수는 window
객체의 프로퍼티가 된다.
하지만 let
, const
로 선언한 변수는 그렇지 않는다.
var x = 100;
console.log(window.x); // ✅ 100
let y = 200;
console.log(window.y); // ❌ undefined
사용 가이드
- 기본적으로
const
를 기본값으로 사용한다. - 값의 변경이 필요할 때만 **
let
**을 사용한다. var
는 사용하지 않는다. (버그 발생 가능성이 높음)
정리
구분 | var | let | const |
---|---|---|---|
중복 선언 | 가능 | 불가능 | 불가능 |
재할당 | 가능 | 가능 | 불가능 |
스코프 | 함수 스코프 | 블록 스코프 | 블록 스코프 |
호이스팅 | 선언+초기화(undefined) | 선언만(TDZ 존재) | 선언만(TDZ 존재) |
전역 객체 등록 여부 | 등록됨(window.a) | 등록 안 됨 | 등록 안 됨 |
참고 용어
- TDZ(Temporal Dead Zone):
let
/const
변수가 선언되었지만 초기화되지 않은 시점에서 접근하면 발생하는 오류 구간