var, let, const는 자바스크립트에서 변수를 선언하기 위해 사용하는 키워드이다.
ES6이전에는 var만을 이용해 변수를 선언하고 사용했으나 ES6이후 let과 const가 추가되었고 이후부터 var를 사용할 수 없는 것은 아니지만 let과 const만을 사용하는 것이 바람직하다.
호이스팅
변수 및 함수 선언이 코드 실행 전에 물리적인 위치에 상관없이 선언문이 최상단으로 끌어올려지는 현상
(실제로 코드가 이동하는 것은 아님)

var로 변수를 선언했을때의 과정이다.
var은 호이스팅이 발생할때 선언과 초기화가 같이 이뤄진다.
console.log(foo); // undefined
var foo = 1;
console.log(foo); // 1
위 코드처럼 foo라는 변수를 선언하기 전 콘솔로 foo라는 변수를 출력했지만 undefined가 출력된다. 위에서 말했듯 var는 호이스팅될때 선언과 초기화(자동으로 undefined)가 같이 이뤄지기 때문에 에러가 뜨지않고 undefined가 뜨게된다.
var a = 1;
console.log(a); // 1
var a = 2;
console.log(a); // 2
var 키워드로 선언한 변수는 var키워드를 다시 사용해 같은 이름으로 변수를 중복하여 선언할 수 있다. 이로 인해 변수명이 중복된다면 언제든 값이 변할 수 있기 때문에 위험하다.
var a = 1;
console.log(a); // 1
a = "홍길동"
console.log(a); // "홍길동"
var는 언제든 값이 변경될 수 있어 위험하다.
function example() {
if (true) {
var x = 10;
console.log(x); // 10
}
console.log(x); // 10
}
example();
console.log(x); // ReferenceError: x is not defined
var는 함수 스코프를 갖기 때문에 변수가 함수 내에서 선언되면 함수 내에서만 유효하다.
위 코드에서 var x = 10;은 함수 example내에 선언되었다. if 블록 내부에서 선언된 변수 x는 해당 블록 외부(if문 다음의 console)에서도 접근할 수 있다.
하지만 함수 외부에서는 x에 접근할 수가 없다.

console.log(foo); // ReferenceError
let foo = 1;
console.log(foo); // 1
console.log(fff); // ReferenceError: Cannot access 'fff' before initialization
const fff = 1;
console.log(fff); // 1
let도 호이스팅 되지만 var과는 다르게 동작한다.
let은 호이스팅되어 선언단계에 들어가지만 이후 일시적 사각지대(TDZ)에 빠지게된다. 이후 코드를 읽어나가며 let foo = 1; 이라는 코드를 만났을때 1이라는 값이 할당되게 된다.
따라서 아래 코드처럼 할당을 하기전 변수에 접근하면 TDZ에 있는 변수에 접근 하는 것이기 때문에 에러가 발생 하는 것이다.
console.log(foo); // ReferenceError
let foo = 1;
let은 var과 다르게 중복 선언이 불가능 하다
let a = 1;
console.log(a);
let a = 5;
console.log(a);
Uncaught SyntaxError: Identifier 'a' has already been declared 에러 발생
let a = 1;
console.log(a); // 1
a = 5;
console.log(a); // 5
중복선언은 불가능하지만 재할당은 가능하다.
function example() {
if (true) {
let x = 10;
console.log(x); // 10
}
console.log(x); // ReferenceError: x is not defined
}
example();
let은 블록 스코프를 갖기 때문에 블록을 나누어준 { }안에서만 유효하며 해당 블록을 벗어나면 더이상 유효하지 않다.
const역시 호이스팅 되지만 var과 let과는 다소 다르다.
cosnt는 반드시 변수를 선언하고 동시에 초기화를 해야 한다.
또한 할당된 값은 변경할 수 없다.
const도 let과 마찬가지로 중복선언이 불가능하다.
const a = 1;
const a = 5;
Uncaught SyntaxError: Identifier 'a' has already been declared 에러 발생
const는 재할당 또한 불가능하다.
const a = 1;
a = 5;
Uncaught TypeError: Assignment to constant variable. 에러발생
const로 선언한 변수나 객체에 대한 재할당은 불가능하지만 객체안의 속성을 바꾸는 건 가능하다.
const men = {
name:"홍길동",
age:20,
}
console.log(men.name); // "홍길동"
men.name = "이름바꾸기?";
console.log(men.name); // "이름바꾸기?"
정리 요약
1. 자바스크립트에서는 변수든 함수든 호이스팅 된다.
2. var키워드는 사용하지말자
3. 일단 const를 이용해 선언하고 사용하자
4. 값이 바뀌는 변수라면 let을 사용을 고려해보자
| 키워드 | 중복선언 | 재할당 | 호이스팅 | 스코프 | TDZ | 생성순서 |
|---|---|---|---|---|---|---|
| var | O | O | O | 함수 | X | 1. 선언 및 초기화 2. 할당 |
| let | X | O | O | 블록 | O | 1. 선언 2. 초기화 3. 할당 |
| const | X | X | O | 블록 | O | 1. 선언 + 초기화 + 할당 |
출처 및 이미지
kasran1 - 블로그
MDN - let
MDN - const