전공공부/자바스크립트 (JAVASCRIPT)

[자바스크립트] 호이스팅 (Hoisting)

jooona 2022. 2. 17. 00:20
반응형

호이스팅?

호이스팅이란 함수 내부에 있는 모든 선언들을 함수 유효 범위의 최상단에 선언하는 것을 말합니다.

 

다시 말해, 함수 실행 전 Parser가 해당 함수를 훑으면서 변수, 함수 선언들에 대한 정보를 저장하고 있다가 최상단으로 끌어올려서 먼저 처리하는 것을 뜻합니다.

 

 

자바와 한번 비교해보겠습니다.

 

1
2
3
4
5
6
7
 public static void main(String[] args) {
 
    a = 0;
    int a;
 
    System.out.println(a);
}
cs

 

자바에서 위와 같은 코드를 작성하면 당연하게도 컴파일 에러가 발생하며 프로그램을 실행조차 할 수 없게 됩니다. 하지만 자바 스크립트에서는 다릅니다. 호이스팅으로 인해 아래와 같은 코드도 정상적으로 작동합니다.

 

1
2
3
= 1;
var a;
console.log(a);
cs

 

비록 a의 사용보다 선언이 더 늦었지만 호이스팅으로 인해 2번째 줄이 가장 먼저 실행되면서 오류 없이 작동하는 것이죠. 3번째 줄에서 결괏값은 1이 정상적으로 출력됩니다.

 

Undefined

다음과 같은 코드에서 결과값은 어떻게 나올까요?

 

1
2
3
4
console.log(a);
= 1;
var a;
console.log(a);
cs

 

정답은...?

 

1번째 줄은 "undefined"가, 3번째 줄은 1이 출력되게 됩니다. 이와 같이, 선언은 되었으나 초기화가 되지 않았다면 결과값은 undefined가 됩니다.

 

Not Defined

그렇다면 다음과 같은 경우는 어떨까요?

 

1
2
3
4
5
6
7
8
console.log(a);
console.log(b);
 
var a= 2;
 
function foo(){
    var b=1;
}
cs

 

 

1번째 줄에서 a는 호이스팅으로 인해 undefined가 출력됩니다. 밑에서 2로 초기화해주었지만, 호이스팅은 선언만 끌어올려서 작동하는 것이기 때문에 2라는 값은 아직 들어가지 않은 것이죠. 4번째 줄이 실행될 때 2라는 값이 들어가겠네요.

 

그렇다면 2번째 줄은 어떨까요? b라는 변수는 foo()라는 함수 안에 선언되어있기 때문에 호이스팅이 발생해도 foo() 함수 내에서만 일어나게 됩니다. 글의 머리 부분에서도 말했듯이 호이스팅은 함수 유효 범위 내에서 가장 위로 선언을 끌어 올리는 역할을 하기 때문에, b의 선언은 foo() 함수를 벗어나지 못합니다.

 

그래서 2번째 줄에서 b는 아예 선언조차 될 수 없고, 따라서 "b is not defined"라는 에러를 결과로 출력합니다.

 

제어문에서의 호이스팅

 

마지막으로 코드를 하나 보겠습니다.

 

1
2
3
4
5
for(var i=1; i<5;i++){
    console.log(i);
}
 
console.log(i);
cs

 

위와 같은 경우라면 5번째 줄에서 어떤 결과가 나올까요? i 변수가 for문 안에 선언되어 있으니까 5번째 줄에서는 not defined를 출력할까요? 

 

아닙니다. 호이스팅은 if, while, for와 같은 제어문의 단위가 아닌 함수 단위로 실행되기 때문에 for문 안에 선언된 i 변수는 호이스팅 됩니다. 따라서 for문을 돌면서 1, 2, 3, 4를 차례로 출력하고 5번째 줄에서는 5를 출력하게 되겠네요.

반응형