자바스크립트에서는 변수를 선언할 때 var, let, const 이렇게 세가지 키워드를 이용해 선언할 수 있다.
ES5까지 변수를 선언할 수 있는 유일한 방법은 var만 있었는데 ES6에서 var의 문제점에 대응하기 위해서 let과 const가 생겨났다.
이 세가지가 선언, 할당, 범위에서 차이가 나는데 헷갈리지 않게 자세하게 정리해보고자 한다 !
1️⃣ 중복 선언
var : 중복 선언이 가능하다
var name = "안녕"
console.log(name) //안녕
var name = "하이"
console.log(name) //하이
var은 중복해서 선언이 가능하다. 이 경우에, 마지막에 할당된 값이 변수에 저장된다.
변수를 유연하게 사용할 수 있다는 장점이 있지만, 기존에 선언해둔 변수의 존재를 까먹고 값을 재할당하게 되는 등의 실수가 발생하기 쉽다.
let, const : 중복 선언이 불가능하다
let name = "딸기"
console.log(name) //딸기
let name = "초코"
console.log(name) //Uncaught SyntaxError: Identifier 'name' has already been declared
let과 const의 경우 중복해서 선언이 불가능하다. 이미 선언한 변수를 다시 선언할 경우에 에러가 발생한다.
따라서 var에 비해서 코드의 안정성을 높여줄 수 있다.
2️⃣ 재할당
var,let : 재할당이 가능하다
var name = "안녕";
console.log(name); //안녕
name = "하이";
console.log(name); //하이
let hi = "딸기";
console.log(hi); //딸기
hi = "바나나";
console.log(hi); //바나나
var과 let의 경우에는 재할당이 가능하다.
변수 선언 및 초기화 이후에 반복해서 다른 값을 재할당 할 수 있다.
const : 재할당이 불가능하다
const name = "초코"
console.log(name) //초코
name = "바나나"
console.log(name) //Uncaught SyntaxError: Identifier 'name' has already been declared
const는 값의 재할당이 불가능한 상수이다.
따라서 처음에 선언 및 초기화하고 나면 다른 값을 재할당 할 수 없다.
var또는 let과 다르게 const는 반드시 값과 선언을 동시에 정의해야 한다.
3️⃣ 스코프 유효범위
var : 함수 레벨 스코프 (function-level scope)
var i = 10;
for (var i = 0; i < 3; i++) {
console.log(i); // 0 1 2
}
console.log(i); // 3
var은 함수 내부에 선언된 변수만 지역변수로 한정하며, 나머지는 모두 전역변수로 간주한다.
따라서 for문에서 var 키워드로 선언한 변수 i는 for문의 외부에서 참조가 가능하다.
따라서 위의 코드의 경우 마지막에 2를 출력하고 i가 ++ 되어서 맨 아랫줄에 3이 출력된다.
let, const : 블록 레벨 스코프 (block-level scope)
let foo = 1; // 전역변수
{
let foo = 2; // 지역변수
let bar = 3; // 지역변수
}
console.log(foo); // 1
console.log(bar); // ReferenceError: bar is not defined
let과 const는 모든 코드 블록 (함수, if문, for문, while문, try/catch문 등)을 지역 스코프로 인정하는 블록 레벨 스코프를 따른다.
따라서 위의 코드 블록 내에서 선언된 foo 변수와 bar 변수는 지역 변수로, 전역에서는 bar 변수를 참조할 수 없다.
4️⃣ 변수 호이스팅 방식
자바스크립트에서는 코드를 실행하기 전에 변수 선언문을 미리 실행하기 때문에 뒤에서 선언된 변수도 앞의 코드에서 참조할 수 있게 된다.
이를 변수의 호이스팅이라고 한다.
var : 호이스팅 시 undefined를 반환한다
// 이 시점에는 변수 호이스팅에 의해 이미 foo 변수가 선언되었다. (1. 선언단계)
// 변수 foo는 undefined로 초기화되었다. (2. 초기화단계)
console.log(foo); // undefined
// 변수에 값을 할당한다. (3. 할당단계)
foo = 123;
console.log(foo); // 123
// 변수 선언은 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 실행된다.
var foo;

var은 변수의 선언과 초기화가 동시에 일어난다.
따라서 호이스팅시에 선언이 되자마자 undefined로 초기화가 되어 undefined를 반환하게 된다.
즉, 변수 호이스팅에 의해 var 키워드로 선언한 변수는 변수 선언문 이전에 참조할 수 있다.
단, 할당문 이전에 변수를 참조하면 언제나 undefined를 반환한다.
변수 선언문 이전에 변수를 참조하는 것은 에러를 발생시키지는 않지만, 프로그램의 흐름상 맞지 않을 뿐더러 가독성을 떨어뜨리고 오류를 발생시킬 수 있다.
let, const : 호이스팅 시 ReferenceError를 반환한다
console.log(foo); // ReferenceError: foo is not defined
let foo;

let, const 키워드로 선언한 변수는 호이스팅이 발생하지 않는 것처럼 동작하지만, let과 const도 호이스팅이 발생한다.
이처럼 let 키워드로 선언한 변수를 변수 선언문 이전에 참조하면 참조 에러가 발생한다.
let과 const는 var과 다르게 선언 단계와 초기화 단계가 분리되어 진행된다.
즉, 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언 단계가 먼저 실행되지만, 초기화 단계는 변수 선언문에 도달했을 때 실행된다.
초기화 단계가 실행되기 전에 접근하려고 하면 메모리가 할당되지 않은 상태라 참조 에러가 발생한다.
이렇게 스코프의 선언 시작부터 초기화 전까지 변수를 참조할 수 없는 구간을 일시적 사각지대 (TDZ) 라고 부른다.
TDZ에 관한 내용은 저번에 글을 써두었으니, 자세히 알고싶다면 읽어보면 좋을 것 같다 !
[CS] TDZ (Temporal Dead Zone) 이란?
let과 const는 호이스팅 시에 변수는 선언되고 초기화는 되지 않아 ReferenceError가 발생하며, TDZ에 빠지게 된다.TDZ에 빠진다는 것은 알고 있었지만 정확하게 TDZ가 뭔지는 알지 못해서 한번 제대로 알
lnk5324.tistory.com
🙋🏻♀️ 언제 어떻게 사용하는게 좋을까?
var은 재선언 / 재할당이 가능하기에 예기치 않은 오류를 발생시킬 수 있다.
따라서 기본적으로는 const와 let을 이용해서 변수를 선언하는 것이 좋고,
값을 재할당 할 경우에는 let 그렇지 않은 경우에는 const를 디폴트로 사용하는 것이 좋다.
'JavaScript' 카테고리의 다른 글
| [JavaScript] JavaScript의 비동기 프로그래밍 ( 콜백함수, Promise , async/await ) (0) | 2025.08.20 |
|---|---|
| [JavaScript] 자바스크립트는 싱글 스레드 언어인데 어떻게 비동기 처리가 가능할까? (0) | 2025.08.18 |
| [JavaScript] TDZ (Temporal Dead Zone) 이란? (0) | 2025.08.16 |
| [JavaScript] 자바스크립트의 실행 컨텍스트란 무엇일까? (4) | 2025.08.14 |