Featured image of post Javascript - Hoisting

Javascript - Hoisting

자바스크립트 학습

hoist라는 단어의 사전적 정의는 “끌어올리기” 라는 뜻이다. 자바스크립트가 실행될때 선언된 모든 변수 선언부가 코드의 가장 위로 끌어올려진 것 처럼 처리된다.

호이스트를 통해 변수의 정의가 그 범위에 따라 선언과 할당으로 분리된다. 즉, 변수가 함수 내에서 정의되었을 경우, 선언이 함수 최상위로, 함수 바깥에서 정의되었을 경우, 전역 컨텍스트의 최상위로 변경이 된다.

1
2
3
4
5
6
7
8
9
function getX() {
    console.log(x); // undefined
    
    var x = 100;
    
    console.log(x); // 100
}

getX();

위와 같이 정의 되었을때, 아래와 같이 해석된다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function getX() {
    var x;
  
    console.log(x);
    
    x = 100;
    
    console.log(x);
}

getX();

선언문은 항상 자바스크립트 엔진 구동시 가장 최우선으로 해석하므로 호이스팅 되고, 할당 구문은 런타임 과정에서 이루어지기 때문에 호이스팅 되지 않는다.

함수의 호이스팅

함수가 자신이 위치한 코드에 상관없이 함수 선언문 형태로 정의한 함수의 유효범위는 전체 코드의 맨 처음부터 시작한다. 함수 선언이 함수 실행 부분보다 뒤에 있더라도 자바스크립트 엔진이 함수 선언을 끌어올리는 것을 의미한다.

1
2
3
4
5
6
7
foo();

function foo(){
    console.log(hello);
};

// console> hello

foo 함수에 대한 선언을 호이스팅하여 global 객체에 등록시키기 때문에 hello가 제대로 출력된다.

오류 사례

1
2
3
4
5
6
7
foo();

var foo = function() {
    console.log(hello);
};

// console> Uncaught TypeError: foo is not a function

예제의 함수 표현은 함수 리터럴을 할당하는 구조이기 때문에 호이스팅 되지 않으며 그렇기 때문에 아래와 같이 해석되어 런타임 환경에서 Type Error를 발생시킨다.

1
2
3
4
5
6
7
8
var foo;

foo(); // foo = undefined
// console> Uncaught TypeError: foo is not a function

foo = function( ) {
    console.log(hello);
};