Javascript

호이스팅 (Hoisting)

Yuna_dev 2021. 6. 20. 23:21

1. 호이스팅이란

  • 호이스팅은 자바스크립트 고유의 특징으로, 식별자를 선언하는 과정에서 발생하는 현상이다.
  • 선언문이 전체 소스코드의 중간에 있더라도 어디에 있든 상관없이, 선두로 끌어 올려진 것처럼 동작하는 것을 호이스팅이라고 말한다.
  • 자바스크립트 엔진은 소스코드를 한줄씩 순차적으로 실행하기에 앞서 평가 과정을 거친다.
  • 다시말해서 JS 소스코드를 parsing할 때 평가단계(런타임 이전)와 실행단계(런타임)로 나눠서 볼수 있는데, 소스 코드의 평가 과정에서는 JS 엔진은 변수 선언을 포함한 모든 선언문을 찾아내어 먼저 실행한다. 그 후, 평가과정이 끝나고 실행단계에서 소스코드를 상위부터 순차적으로 실행한다.
  • 이때문에 변수 선언보다 그 변수의 참조 코드가 앞서 상위에 있더라도 위치에 상관없이 어디서든지 변수를 참조할 수 있다.
  • 가장 기본적인 변수 선언 뿐만아니라 var, let, const, function, class 키워드를 사용해서 선언하는 모든 식별자는 호이스팅이 된다.
  • 이 때 주의할 점은 선언은 호이스팅 되지만 할당은 호이스팅 되지 않는다는 것이다. 그래서 선언된 변수나 함수를 참조할 수 있지만 그에 할당된 값을 참조할 수는 없다.
console.log(yoo) // undefined (선언과 동시에 암묵적인 초기화, 할당문의 실행은 X)
var yoo = 1; // 값의 할당
console.log(yoo) // 1

 

2. 선언 키워드에 따른 호이스팅

2.1 var 키워드

    • var 키워드로 선언한 변수는 소스코드 평가단계에서 선언과 동시에 암묵적으로 undefined로 초기화가 된다. 즉, 선언단계와 초기화단계가 동시에 실행되는 것이다.변수선언의 키워드에 따라 조금의 차이가 발생한다.

2.2 let, const 키워드

    • 그에 반해 let, const 키워드로 선언한 변수는 소스코드 평가단계에서 선언만 되고, 초기화는 되지 않는다. 즉, let, const 키워드로 선언한 변수는 선언단계와 초기화 단계가 분리되어 진행된다.
    • 런타임 이전에 선언단계가 진행되지만, 초기화단계는 런타임에서 해당 선언문에 도달했을 때 실행이 된다.
    • 따라서 실제로 호이스팅은 되지만 선언문 이전에 참조를 하면 참조에러가 발생하여 호이스팅이 되지 않는 것처럼 보인다.
    • 위와 같이 스코프의 시작 지점부터 초기화 단계까지 변수를 참조할 수 없는 구간을 일시적 사각지대(Temporal Dead Zone)라고 부른다.
    • 그럼 호이스팅 되지만 참조만 할수 없다는 것을 어떻게 알수 있을까? 이는 다음의 코드를 실행해보면 알수 있다.
let test = 5; // 전역 변수
{
    console.log(test); // ???  => ReferenceError
    let test =10; // 지역 변수
}
  • let, const 키워드가 호이스팅되지 않는다면 위의 console에서는 전역변수 test의 값을 출력해야 한다. 하지만 let 키워드로 선언한 변수도 여전히 호이스팅이 발생하기 때문에 참조에러가 발생하는 것이다.
  • 즉, let, const 로 선언한 변수도 호이스팅이 되지만 호이스팅이 되지 않는것처럼 동작하는 것이다.