JavaScript 에서 변수를 선언할 때 사용하는 var, let, const
의 차이점을 알아보자🏃♂️
var temp = "변수 선언";
console.log(temp); // 변수 선언
var temp = "변수 다시 선언";
console.log(temp); // 변수 다시 선언
var 의 경우에는 이미 선언한 변수 명을 이용해서 다시 변수를 선언해도 에러가 발생하지 않고 정상적으로 선언되고, 출력되는 것을 확인 할 수 있다.
이러한 특징이 편리하다는 장점으로 와닿을 수도 있지만 🤔, 코드 양이 많아지고 변수 명이 겹치게 되면 큰 문제가 발생할 수 있기 때문에 이러한 장점아닌 단점을 보완하기 위해서 let
, const
가 추가 되었다.
let temp = "변수 선언";
console.log(temp); // 변수 선언
let temp = "변수 다시 선언";
console.log(temp);
// Uncaught SyntaxError: Identifier 'temp' has already been declared
let 을 이용해서 변수를 재선언 했더니 temp
는 이미 선언되었다는 에러가 발생하게 된다.
let temp = "변수 선언";
console.log(temp); // 변수 선언
temp = "변수 재할당";
console.log(temp); // 변수 재할당
하지만 재선언 이 아닌 재할당 을 했더니 문제없이 다시 할당된 문자열이 출력되는 것을 확인 할 수 있다.
const temp = "변수 선언";
console.log(temp); // 변수 선언
const temp = "변수 다시 선언";
console.log(temp);
// Uncaught SyntaxError: Identifier 'temp' has already been declared
const temp2 = "두번째 변수 선언";
console.log(temp); // 두번째 변수 선언
temp2 = "두번째 변수 재할당";
console.log(temp);
// Uncaught TypeError: Assignment to constant variable.
const 를 이용해서 변수를 재선언 했더니 temp
는 이미 선언되었다는 에러가 발생하게 된다.
또한 재할당 을 시도하게 되면 constant
변수는 재할당이 불가능 하다는 에러가 발생하게 된다.
⚡Hoisting (호이스팅) : 변수나 함수를 정의하는 코드보다 사용하는 코드가 먼저 등장할 수 있다.
JavaScript는 ES6부터 let
, const
를 포함하여 모든 선언 (var, let, const, function, function*, class)을 Hoisting 한다.
console.log(a); // undefined
var a = "var 테스트";
console.log(a); // var 테스트
var 의 경우에는 에러가 발생하진 않고 undefined
값을 반환한다.
console.log(a); // Error: Uncaught ReferenceError: a is not defined
let a = "let 테스트";
console.log(b); // Error: Uncaught ReferenceError: b is not defined
const b = "const 테스트";
하지만 let, const 의 경우에는 에러가 참조 에러가 발생하게 된다.
그렇다면 Hoisting 을 아예 지원하지 않는 것일까?
let temp = 1;
{
console.log(temp); // Uncaught ReferenceError: Cannot access 'temp' before initialization
let temp = 2;
}
만약 Hoisting이 안됐다면 , console.log(temp)
를 실행했을 때 가장 상위에 있는 temp
를 참조해서 1
이 출력되어야 하는데, Hoisting이 되기 때문에 let temp = 2
가 상위로 올려져서 에러가 발생하게 된 것이다.
변수는 세가지 단계를 거쳐서 생성 되게 되는데
변수 선언 단계와 초기화 단계 사이를 일시적 사각지대(Temporal Dead Zone; TDZ) 라고 부른다.
var
로 선언된 변수의 경우에는 선언 단계 + 초기화 단계가 한번에 이루어지지만,
let
으로 선언된 변수의 경우에는 선언 단계, 초기화 단계가 나누어져서 각각 이루어진다.
이러한 특성 때문에 TDZ에 빠져 위와 같은 현상이 나타나게 되는 것이다 😢
변수 재선언 | 변수 재할당 | |
---|---|---|
var | 가능 | 가능 |
let | 불가능 | 가능 |
const | 불가능 | 불가능 |