포스트

[JavaScript] var, let, const

[JavaScript] var, let, const

JavaScript에서 변수를 선언하는 방법은 var, let, const가 있다.
요즘은 대부분 letconst를 사용하고, var는 레거시 코드에서 주로 만난다.

이 글은 아래 3가지만 확실하게 정리하는 게 목표이다.

  • 스코프(scope): 변수가 “어디까지” 보이는가?
  • 재선언/재할당: 같은 이름으로 다시 선언 가능한가? 값 변경 가능한가?
  • 호이스팅(hoisting): 선언이 “어떻게” 끌어올려지는가?


1) 스코프: 함수 스코프(var) vs 블록 스코프(let/const)

var는 함수 스코프

varif, 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 라이센스를 따릅니다.