[JavaScript] var, let, const 차이점

April 12, 2021 · 6 mins read label-icon Javascript

자바스크립트에는 var, let, const 3가지의 변수 선언 방식이 있다.

간단하게는 알고 있지만, 구체적으로 어떤 차이점이 있는지 정리해보려고 한다.


차이점을

1. 재선언과 재할당
2. 레벨 스코프
3. 호이스팅

이 3가지로 분류해서 정리하려고 한다.

1. 재선언과 재할당

  • var 의 경우 재선언과 재할당 모두 가능하다.
1
2
3
4
5
var age = 20;
console.log(age); // 20

var age = 30;
console.log(age); // 30
  • let 의 경우 재선언은 불가능하고 재할당은 가능하다.
1
2
3
4
5
6
// 재선언은 불가능

let age = 20;
console.log(age); // 20

let age = 30; // Uncaught SyntaxError: Identifier 'age' has already been declared
1
2
3
4
5
6
7
// 재할당은 가능

let age = 20;
console.log(age); // 20

age = 30;
console.log(age); // 30
  • const 의 경우 재선언과 재할당 모두 불가능하다.
1
2
3
4
5
6
// 재선언 불가능

const age = 20;
console.log(age); // 20

const age = 30; // Uncaught SyntaxError: Identifier 'age' has already been declared
1
2
3
4
5
6
// 재할당도 불가능

const age = 20;
console.log(age); // 20

age = 30; // Uncaught SyntaxError: Identifier 'age' has already been declared

2. 레벨 스코프

  • var함수 레벨 스코프 (function-level scope) 를 따른다.
  • constlet블록 레벨 스코프 (block-level scope) 를 따른다.
  • 스코프에 관련된 정보는 해당 포스팅에서 확인할 수 있다.

3. 호이스팅

호이스팅이란 함수 안에 있는 선언을 최상단으로 끌어 올리는 (Hoisting) 것을 의미한다.

  • var 의 경우

기존 코드

1
2
3
var a = 10;

console.log(a); // 10

호이스팅 결과

1
2
3
4
5
var a; // 선언이 최상단으로 끌어올려짐

a = 10; // 할당

console.log(a); // 결과 : 10
  • let, const 의 경우

var 랑 다르게 ReferenceError 가 발생한다.

1
2
3
4
5
6
7
console.log(a); // undefined
console.log(b); // ReferenceError
console.log(c); // ReferenceError

var a = 'a';
let b = 'b';
const c = 'c';

이는 TDZ (Temporal Dead Zone) 에서 에러가 나타나기 때문이다.

TDZ (Temporal Dead Zone)

변수의 선언에는 총 3단계가 있다.

  1. 선언 단계 (Declaration phase)
  2. 초기화 단계 (Initialization phase)
  3. 할당 단계 (Assignment phase)
  • var 는 선언 단계와 초기화 단계가 동시에 진행된다.
  • let 은 각각 따로 진행된다.
  • const 는 3단계가 동시에 진행된다.

TDZ (Temporal Dead Zone) 는 스코프의 시작점부터 초기화 단계까지의 구간을 의미한다.

js-in-tdz-img 이미지 출처 : https://dmitripavlutin.com/javascript-variables-and-temporal-dead-zone/

TDZ 로 인해 letconst 가 호이스팅이 되어 변수가 선언되었지만 초기화 단계가 진행되지않아 ReferenceError 가 생기는 것이다.

ReferenceError 가 발생해서 letconst 가 호이스팅이 되지 않는 것이라고 생각할 수도 있지만, 호이스팅이 된다.

1
2
3
4
5
6
7
8
9
let age = 35;

(function () {
    // (*)
    console.log(age);
    let age = '27'; // ReferenceError: Cannot access 'age' before initialization
})();

// 6번 줄의 변수가 함수의 최상단(*)으로 호이스팅 되어 ReferenceError 가 발생한다.

요약

  • var재선언과 재할당 모두 가능하다. 함수 레벨 스코프 (function-level scope) 를 따른다.
  • let재선언은 불가능하고 재할당은 가능하다. 블록 레벨 스코프(block-level scope) 를 따른다.
  • const재선언과 재할당 모두 불가능하다. 블록 레벨 스코프(block-level scope) 를 따른다.
  • letconstES6 부터 추가되었다.
  • letconst불변성의 차이가 있다.
  • 변수의 선언 단계는 선언, 초기화, 할당 총 3가지의 단계가 있다.
  • letconst호이스팅이 되지만 TDZ 로 인해 되지 않는 것처럼 보인다.

마무리

간단하게 var 는 좋지 않고 let 은 값을 바꿀 수 있고 const 값을 바꿀 수 없다! 라고만 생각했었는데 이번 기회에 더욱더 명확하게 차이점을 알 수 있었다.