변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징입니다.
❗ 변수 선언뿐만 아니라 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'}