
변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징입니다.
❗ 변수 선언뿐만 아니라 var, let, const, function, function*, class 키워드를 사용해서 선언하는 모든 식별자는 호이스팅이 됩니다. 모든 선언문은 런타임(실행) 이전 단계(평가)에서 먼저 실행되기 때문입니다. (실행 컨텍스트 참고)
var 키워드로 선언한 변수는 중복선언이 가능합니다.var x = 1;
var y = 1;
var x = 100;
var y;
console.log(x); // 100
console.log(y); // 1
var 키워드로 선언한 변수는 함수 코드 블록만을 스코프로 인정합니다.var x = 1;
if (true) {
var x = 10;
}
console.log(x); // 10
var 키워드는 호이스팅에 의해 선언문 이전에 참조할 수 있습니다. 단 결과는 undefined가 나오게 됩니다.foo를 실행 시켜 foo를 Lexical Environment의 환경 레코드에 키로 등록을 하게됩니다. 이때 동시에 초기화를 진행해 undefined가 할당 됩니다.console.log(foo); // undefined
foo = 123;
console.log(foo); // 124
var foo;

let 키워드로 변수를 중복 선언할 경우 에러가 발생하게 됩니다.var foo = 123;
var foo = 456;
let bar = 123;
let bar = 456; // SyntaxError
let 키워드로 선언한 변수는 코드 블록을 스코프로 인정하는 블록 레벨 스코프를 따릅니다.let foo = 1;
{
let foo = 1;
let bar = 3;
}
console.log(foo); // 1
console.log(bar); // Reference Error
var와 마찬가지로 let도 호이스팅이 일어나나 발생하지 않는것 처럼 동작합니다.undefined로 초기화되는 var와 달리 let은 선언단계와 초기화 단계가 분리되어 진행됩니다. 만약 초기화 단계 이전에 변수에 접근하려 하면 에러가 발생합니다.TDZ(Temporal Dead Zone)이란?
스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을 의미합니다.
console.log(foo);
let foo; // 변수 선언문에서 초기화 단계가 진행됩니다.
console.log(foo); // undefined
foo = 1;
console.log(foo);

let foo = 1;
{
console.log(foo); // Reference Error
let foo = 2;
}
만약 호이스팅이 발생하지 않았다면, 블록 코드에서 결과는 에러가 아닌 1이여야 합니다.
const 키워드는 반드시 선언과 동시에 초기화가 일어나야 합니다.let과 마찬가지로 호이스팅이 발생하나, 일어나지 않은 것 처럼 동작합니다.let과 달리 한번 값을 할당한 변수에 다른 값을 재할당 할 수 없습니다.const person = {
name: 'Lee';
}
person.name = 'Kim';
console.log(person); //{name: 'Kim'}