Skip to main content

JavaScript: var, let, const 차이점 정리 (변수 호이스팅 포함)

1. 중복 선언 가능 여부

키워드

중복 선언 가능 여부

var

✅ 가능

let

❌ 불가능 (SyntaxError 발생)

const

❌ 불가능 (SyntaxError 발생)

  • var는 동일한 스코프 내에서 같은 이름으로 여러 번 선언해도 에러 없이 동작한다.
  • letconst는 같은 이름으로 중복 선언할 수 없다.

2. 재할당 가능 여부

키워드

재할당 가능 여부

var

✅ 가능

let

✅ 가능

const

❌ 불가능 (TypeError 발생)

설명:

  • var, let : 값의 재할당이 가능한 변수다. 변수 선언 및 초기화 이후에 반복해서 다른 값을 재할당 할 수 있다.
  • ​const : 상수(constant) 선언에 사용되며, 초기화 이후 값 변경이 불가하다. 단, 객체나 배열은 내부 속성/요소 변경은 가능하다.
  • var 또는 let과 달리, const 선언에서는 반드시 값을 선언과 동시에 정의해야 한다
  • * 재할당이 필요없는 경우, const를 사용해 불필요한 변수의 재사용을 방지하고, 재할당이 필요한 경우 let을 사용하자.
const obj = { a: 1 };
obj.a = 2; // 가능

3. 스코프(Scope)

키워드

스코프 종류

var

함수 스코프 (Function Scope)

let

블록 스코프 (Block Scope)

const

블록 스코프 (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를 참조했기 때문에 에러 발생.

키워드

호이스팅 여부

초기화 상태

var

✅ 선언과 초기화(undefined)

초기화됨

let

✅ 선언만 됨 (TDZ 존재)

초기화 안됨

const

✅ 선언만 됨 (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.varName)

let

❌ 등록 안 됨

const

❌ 등록 안 됨

설명:
브라우저 환경에서는 var로 선언한 전역 변수는 window 객체의 프로퍼티가 된다.
하지만 let, const로 선언한 변수는 그렇지 않는다.

var x = 100;
console.log(window.x); // ✅ 100

let y = 200;
console.log(window.y); // ❌ undefined

사용 가이드

  1. 기본적으로 const를 기본값으로 사용한다.
  2. 값의 변경이 필요할 때만 **let**을 사용한다.
  3. var는 사용하지 않는다. (버그 발생 가능성이 높음)

정리

구분

varletconst

중복 선언

가능

불가능

불가능

재할당

가능

가능

불가능

스코프

함수 스코프

블록 스코프

블록 스코프

호이스팅

선언+초기화(undefined)

선언만(TDZ 존재)

선언만(TDZ 존재)

전역 객체 등록 여부

등록됨(window.a)

등록 안 됨

등록 안 됨


참고 용어

  • TDZ(Temporal Dead Zone):
    let/const 변수가 선언되었지만 초기화되지 않은 시점에서 접근하면 발생하는 오류 구간