JavaScript - Hoisting(호이스팅)

 

호이스팅이란

변수 혹은 함수의 선언 구가 호출을 한 위치보다 아래에 있더라도 끌어올리는 현상을 말한다.

  • 전역 범위(global scope) : 전역 범위에서는 스크립트 단위에서 최상단으로 끌어올려 진다.
  • 함수 범위(function scope) : 함수 범위에서는 해당 함수의 최상단으로 끌어올려 진다.

변수 호이스팅

age = 6;
var age;

age가 먼저 선언되지 않아도 오류 없이 사용이 가능하다.

console.log(age); // undefined
var age = 11;
console.log(age); //11

주의) 할당된 내용은 올라가지 않고 선언 구만 올라간다.
그 결과 첫 번째 console.log는 정의되지 않았다는 undefined가 찍히게 되지만 두 번째 console.log는 할당된 값이 표현된다.

선언 구는 자바스크립트 엔진 구동 시 최우선으로 해석하므로 호이스팅 되고 (선언과 초기화를 한 번에 한다.),
할당 구는 런타임 과정에서 이루어지기 때문에 변수에 할당문에 도달해야 할당되기 때문에 호이스팅 되지 않는다.

이 현상은 var에서만 일어난다. let,const(ES6선언)은 일어나지 않는다.

console.log(foo); // ReferenceError: foo is not defined

let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined

foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1

let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.
즉, 스코프에 변수를 등록(선언단계)하지만 초기화 단계는 변수 선언문에 도달했을 때 이루어진다.
따라서 스코프의 시작 지점부터 초기화 시작 지점까지는 변수를 참조할 수 없다.
이는 변수가 아직 초기화되지 않았기 때문이다. 다시 말하면 변수를 위한 메모리 공간이 아직 확보되지 않았기 때문이다.
스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 ‘일시적 사각지대(Temporal Dead Zone; TDZ)’라고 부른다.
결국 let도 호이스팅은 일어나지만 TDN에 빠지게 되어 호이스팅이 일어나지 않아 보인다. (참조적 오류가 발생)

함수 호이스팅

hoisting(); // 호이스팅!!
NoHoisting(); // Uncaught TypeError: NoHoisting is not a function

function hoisting(){
    console.log("호이스팅!!");
    }

var NoHoisting = function(){
      console.log("호이스팅 안된다");
    }

함수 선언문은 호이스팅 되어 호이스팅!!가 찍히지만
함수 리터럴 방식은 호이스팅이 되지 않는다. (변수 호이스팅 발생)



참고자료 : https://poiemaweb.com/es6-block-scope
      https://asfirstalways.tistory.com/197