
JavaScript에서 변수를 선언하는 방법에는 var, let, const가 있다. 이 세 가지는 변수를 선언하는 데 사용되지만 스코프, 재할당 가능 여부, 호이스팅과 관련하여 각각 다른 특징을 가지고 있다. 이 글에서는 var, let, const의 차이점을 자세히 살펴보고, 각 선언 방식이 사용되는 상황에 대해 설명한다.
var로 선언된 변수는 함수 스코프이거나 전역 스코프이다. 블록 기준으로 스코프가 생기지 않기 때문에 블록 밖에서 접근 가능하다.
function example() {
if (true) {
var x = 10;
}
console.log(x); // 10 (블록 밖에서도 접근 가능)
}
example();
같은 스코프 내에서 같은 이름의 변수를 다시 선언할 수 있다. 이는 유지보수 시 변수 이름 충돌 문제를 일으킬 수 있어 권장되지 않는다.
var x = 5;
var x = 10; // 문제없이 재선언 가능
console.log(x); // 10
var로 선언된 변수는 재할당이 가능하다. 즉, 선언 후에도 값을 변경할 수 있다.
var y = 20;
y = 30; // 재할당 가능
console.log(y); // 30
var는 호이스팅된다. 즉, 변수 선언이 실제 코드 상에서는 아래에 있어도, 자바스크립트 엔진이 해당 변수를 최상단으로 끌어올려 사용할 수 있게 한다. 다만, 초기화는 호이스팅되지 않으므로 undefined 값이 먼저 출력될 수 있다.
console.log(x); // undefined
var x = 5;
let은 블록 스코프를 따른다. 즉, 변수가 선언된 중괄호({}) 내에서만 유효하며, 블록을 벗어나면 접근할 수 없다. 이는 더 세밀한 스코프 관리를 가능하게 하여 코드의 안정성을 높여준다.
if (true) {
let y = 20;
console.log(y); // 20
}
console.log(y); // ReferenceError: y is not defined
let은 같은 스코프 내에서 재선언이 불가능하다. 이를 통해 변수 충돌을 방지하고, 실수로 변수를 다시 선언하는 오류를 줄일 수 있다.
let z = 5;
let z = 10; // SyntaxError: Identifier 'z' has already been declared
let으로 선언된 변수도 재할당이 가능하다. 한 번 선언된 변수에 다른 값을 넣을 수 있다.
let a = 10;
a = 15; // 재할당 가능
console.log(a); // 15
let도 호이스팅되지만, var와 달리 TDZ(Temporal Dead Zone)라는 특성을 가진다. 선언된 위치 이전에는 변수에 접근할 수 없으며, 접근 시 ReferenceError가 발생한다.
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 5;
TDZ: 선언은 되었지만 참조는 할 수 없는 사각지대
const도 let과 마찬가지로 블록 스코프를 따른다. 선언된 블록 안에서만 유효하며, 블록 밖에서는 접근할 수 없다.
if (true) {
const b = 30;
console.log(b); // 30
}
console.log(b); // ReferenceError: b is not defined
const로 선언된 변수는 재선언이 불가능하다. 이는 let과 마찬가지로, 같은 스코프 내에서 동일한 변수 이름을 다시 사용할 수 없음을 의미한다.
const c = 5;
const c = 10; // SyntaxError: Identifier 'c' has already been declared
const로 선언된 변수는 재할당이 불가능하다. 이는 상수처럼 한 번 선언된 값을 변경할 수 없다는 의미다. 하지만, 객체나 배열 같은 참조형 데이터는 그 내부의 값은 변경할 수 있다.
const c = 5;
c = 10; // TypeError: Assignment to constant variable.
const obj = { name: 'John' };
obj.name = 'Doe'; // 객체의 속성 값은 변경 가능
console.log(obj.name); // 'Doe'
const도 let과 마찬가지로 호이스팅되지만, TDZ(Temporal Dead Zone) 내에서는 접근할 수 없다. 선언 전에 변수에 접근하면 ReferenceError가 발생한다.
console.log(d); // ReferenceError: Cannot access 'd' before initialization
const d = 15;
| 특성 | var | let | const |
|---|---|---|---|
| 스코프 | 함수 스코프 | 블록 스코프 | 블록 스코프 |
| 재선언 | 가능 | 불가능 | 불가능 |
| 재할당 | 가능 | 가능 | 불가능 |
| 호이스팅 | 가능 (초기화 안 됨) | 가능 (TDZ 적용) | 가능 (TDZ 적용) |
const로 선언하고, 값이 변경될 가능성이 있을 때만 let을 사용하는 것이 좋은 관행이다.var는 함수 스코프를 가지며, 호이스팅 및 재선언이 가능하지만, 버그를 유발할 수 있어 사용을 피하는 것이 좋다.let은 블록 스코프를 지원하며, 재선언이 불가능하고 TDZ를 통해 안정성을 보장한다.const는 상수를 선언할 때 사용하며, 재할당이 불가능하므로 변경되지 않는 값에 적합하다.가능하면 const를 기본값으로 사용하고 재할당이 필요한 경우에만 let을 사용하는 것이 현대 자바스크립트 개발에서 권장되는 방법이다.