All Articles

호이스팅

호이스팅이 뭐야?

  • 자바스크립트의 특이점 중 하나로, 스크립트를 실행하기 전 준비단계에서 var 혹은 function 등 선언문을 찾아 이 변수 혹은 함수를 생성하는 것이다.

호이스팅의 특징

  • 이는 마치 선언문이 해당 스코프의 최상단으로 끌어올려지는 것과 같은 효과라서, 코드 작성 순서상으로 선언문이 더 뒤에 있어도 참조 에러(ReferenceError)가 발생하지 않는다.
  • 하지만 변수에 무언가를 할당하기 전까진 값이 undefined이다. 즉, 선언 - 초기화 - 할당 단계 중, 선언초기화만 호이스팅 되고, 할당은 호이스팅되지 않는다는 것이다.

    • 예시

      function sayHi() {
        alert(phrase);
        var phrase = "Hello";
      } 
      
      sayHi(); // undefined
  • 참고로, 변수가 함수(by 선언문)보다 더 위로 끌어올려진다.
  • “var와 다르게 let이나 const를 쓰면, 호이스팅이 발생하지 않는다”라고 생각할 수 있는데 이는 사실이 아니다. 물론 let을 쓴 선언문이 더 뒤에 있을 경우, 참조 에러가 발생한다. 스코프의 시작에서 변수의 선언문까지 일시적 사각지대(Temporal Dead Zone; TDZ)에 빠지기 때문이다. 하지만 이게 호이스팅이 발생하지 않아서는 아니다. 선언만 호이스팅되고 초기화부터는 호이스팅되지 않기 때문에 접근을 못할 뿐이다. 아래 예시를 보면 이를 알 수 있다. 호이스팅이 일어나지 않았다면 10이 출력되었어야 했을 거다. 하지만 선언이 호이스팅되다보니 TDZ가 생겨 초기화 전에 액세스할 수 없다는 에러가 뜬다.

    let a = 10;
    {
      console.log(a);
      let a = 20;
    }

함수 표현식과 함수 선언문

함수 표현식

  • 실제 실행 흐름이 해당 함수에 도달했을 때 함수를 생성한다. 즉, 실행 흐름이 함수에 도달해야만 그 때부터 해당 함수를 사용(할당, 호출 등)할 수 있다.
  • 예시

    myFun(); // Error!
    
    const myFun = function() {
    console.log("wow~~");
    }

함수 선언문

  • 호이스팅으로 인해, 함수 선언문이 정의되기 전에도 호출할 수 있다.
  • 예시

    myFun(); // wow~~
    
    function myFun() {
    console.log("wow~~");
    }

그럼, var 키워드를 활용한 함수 표현식에서는?

  • 이는 함수 표현식이긴 하지만, var를 통해 값으로서 변수에 할당되는 케이스이다. var의 선언/초기화가 호이스팅되어 해당 스코프 내에서는 어디서든 접근할 수 있지만, 함수를 호출할 수는 없다.

[참고]
https://javascript.info/var
https://ko.javascript.info/function-expressions-arrows