자바스크립트의 호이스팅(Hoisting)에 대해 이해한다.

Edwith 강의 참고

Goal

  • 호이스팅(Hoisting)이란 무엇인지 이해한다.
  • 함수선언문과 함수표현식에서의 호이스팅 차이를 이해한다.
    • let/const와 var 변수 선언에서의 호이스팅 예시
  • 같은 이름의 var 변수 선언과 함수 선언에서의 호이스팅에 대해 이해한다.

호이스팅(Hoisting)의 개념

함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말한다.

호이스팅이란

호이스팅의 대상

함수선언문과 함수표현식에서의 호이스팅

들어가기 전: 함수선언문과 함수표현식의 차이는 다음 POST를 참고하자.

함수선언문에서의 호이스팅

/* 정상 출력 */
function printName(firstname) { // 함수선언문 
    var result = inner(); // "선언 및 할당"
    console.log(typeof inner); // > "function"
    console.log("name is " + result); // > "name is inner value"

    function inner() { // 함수선언문 
        return "inner value";
    }
}

printName(); // 함수 호출 
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 - 위와 동일 --- */
/* 정상 출력 */
function printName(firstname) { 
    var result; // [Hoisting] var 변수 "선언"

    function inner() { // [Hoisting] 함수선언문
        return "inner value";
    }

    result = inner(); // "할당"
    console.log(typeof inner); // > "function"
    console.log("name is " + result); // > "name is inner value"
}

printName(); 

함수표현식에서의 호이스팅

  1. 함수표현식의 선언이 호출보다 위에 있는 경우 - 정상 출력
     /* 정상 */
     function printName(firstname) { // 함수선언문
         var inner = function() { // 함수표현식 
             return "inner value";
         }
            
         var result = inner(); // 함수 "호출"
         console.log("name is " + result);
     }
    
     printName(); // > "name is inner value"
    
     /* 정상 */
     /** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 - 위와 동일 --- */
     function printName(firstname) { 
         var inner; // [Hoisting] 함수표현식의 변수값 "선언"
         var result; // [Hoisting] var 변수값 "선언"
    
         inner = function() { // 함수표현식 "할당"
             return "inner value";
         }
            
         result = inner(); // 함수 "호출"
         console.log("name is " + result);
     }
    
     printName(); // > "name is inner value"
    
  2. 함수표현식의 선언이 호출보다 아래에 있는 경우 (var 변수에 할당) - TypeError
     /* 오류 */
     function printName(firstname) { // 함수선언문
         console.log(inner); // > "undefined": 선언은 되어 있지만 값이 할당되어있지 않은 경우
         var result = inner(); // ERROR!!
         console.log("name is " + result);
    
         var inner = function() { // 함수표현식 
             return "inner value";
         }
     }
     printName(); // > TypeError: inner is not a function
    
     /** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 --- */
     /* 오류 */
     function printName(firstname) { 
         var inner; // [Hoisting] 함수표현식의 변수값 "선언"
    
         console.log(inner); // > "undefined"
         var result = inner(); // ERROR!!
         console.log("name is " + result);
    
         inner = function() { 
             return "inner value";
         }
     }
     printName(); // > TypeError: inner is not a function
    
    • Q. printName에서 “inner is not defined” 이라고 오류가 나오지 않고, “inner is not a function”이라는 TypeError가 나오는 이유?
    • A. printName이 실행되는 순간 (Hoisting에 의해) inner는 ‘undefined’으로 지정되기 때문
    • inner가 undefined라는 것은 즉, 아직은 함수로 인식이 되지 않고 있다는 것을 의미한다.
  3. 함수표현식의 선언이 호출보다 아래에 있는 경우 (const/let 변수에 할당) - ReferenceError
     /* 오류 */
     function printName(firstname) { // 함수선언문
         console.log(inner); // ERROR!!
         let result = inner();  
         console.log("name is " + result);
    
         let inner = function() { // 함수표현식 
             return "inner value";
         }
     }
     printName(); // > ReferenceError: inner is not defined
    
    • let/const의 경우, 호이스팅이 일어나지 않기 때문에 위의 예시 그대로 이해하면 된다.
    • console.log(inner);에서 inner에 대한 선언이 되어있지 않기 때문에 이때는 “inner is not defined” 오류가 발생한다.

호이스팅 우선순위

같은 이름의 var 변수 선언과 함수 선언에서의 호이스팅

TIP 호이스팅 사용 시 주의

관련된 Post

Reference