호이스팅에 대해서 설명해 보세요.

    728x90
    반응형

    목표

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

     

    호이스팅(Hoisting)의 개념

    - 자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.

    • 자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는다.
    • 함수 안에 존재하는 변수/함수선언에 대한 정보를 기억하고 있다가 실행시킨다.
    • 유효 범위: 함수 블록 {} 안에서 유효하다.

    - 즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것이다.

    • 실제로 코드가 끌어올려지는 건 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것이다.
    • 실제 메모리에서는 변화가 없다.

     

     

     

    *** 호이스팅은 변수를 선언하고 초기화했을 때, 선언 부분이 최상단으로 끌어올려지는 현상을 말한다.

    var의 경우 변수를 선언하고 초기화하는 과정이 동시에 일어나서 호이스팅이 발생한다.

    반면 let/const 의 경우 선언과 초기화 단계가 동시에 일어나지 않는다.

    실행 시점에서 실제 선언부를 만날 때 초기화가 이뤄진다. 그 사이의 시간을 TDZ(Temporary Dead Zone)이라고 한다. 즉 실행 컨텍스트에 변수가 선언은 되었으나 메모리가 할당되지 않아 ReferenceError가 발생한다.  함수 호이스팅은 선언문에서 발생한다. 선언된 함수는 상단에서 참조, 호출이 가능하다. 함수 표현식은 결국 변수에 할당하는 모습이라 변수 호이스팅의 사례로 볼 수 있다. 

     

    (변수 선언 3단계: 선언 -> 초기화 -> 할당)

     

     

     

    호이스팅의 대상

    - var 변수 선언과 함수선언문에서만 호이스팅이 일어난다.

    • var 변수/함수의 선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다.
    • let / const 변수 선언과 함수표현식에서는 호이스팅이 발생하지 않는다.
    • (변수 선언 3단계: 선언 -> 초기화 -> 할당)

    - 예시 ( var 변수 vs let / const 변수 )

      console.log("hello");
      var myname = "HEEE"; // var 변수 
      let myname2 = "HEEE2"; // let 변수 
    
    
    
      /** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 - 위와 동일 --- */
      var myname; // [Hoisting] "선언"
      console.log("hello");
      myname = "HEEE"; // "할당"
      let myname2 = "HEEE2"; // [Hoisting] 발생 X

     

    - 예시 ( 함수선언문 vs 함수표현식 )

      foo();
      foo2();
    
      function foo() { // 함수선언문
              console.log("hello");
      }
      var foo2 = function() { // 함수표현식
              console.log("hello2");
      }
    
    
    
    
      /** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 - 위와 동일 --- */
      var foo2; // [Hoisting] 함수표현식의 변수값 "선언"
    
      function foo() { // [Hoisting] 함수선언문
              console.log("hello");
      }
    
      foo();
      foo2(); // ERROR!! 
    
      foo2 = function() { 
              console.log("hello2");
      }

     

    - 호이스팅은 함수선언문과 함수표현식에서 서로 다르게 동작하기 때문에 주의해야 한다.

    • 함수에 할당된 함수표현식은 끌어 올려지지 않기 때문에 이때는 변수의 스코프 규칙을 그대로 따른다.

     

     

    호이스팅 우선순위

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

    - 변수 선언이 함수 선언보다 위로 끌어 올려진다.

     

      var myName = "hi";
    
      function myName() {
          console.log("yuddomack");
      }
      function yourName() {
          console.log("everyone");
      }
    
      var yourName = "bye";
    
      console.log(typeof myName);
      console.log(typeof yourName);
    
    
    
    
      /** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 --- */
      // 1. [Hoisting] 변수값 선언 
      var myName; 
      var yourName; 
    
      // 2. [Hoisting] 함수선언문
      function myName() {
          console.log("yuddomack");
      }
      function yourName() {
          console.log("everyone");
      }
    
      // 3. 변수값 할당
      myName = "hi";
      yourName = "bye";
    
      console.log(typeof myName); // > "string"
      console.log(typeof yourName); // > "string"
      
      
      
      
      
      var myName = "Heee"; // 값 할당 
      var yourName; // 값 할당 X
    
      function myName() { // 같은 이름의 함수 선언
          console.log("myName Function");
      }
      function yourName() { // 같은 이름의 함수 선언
          console.log("yourName Function");
      }
    
      console.log(typeof myName); // > "string"
      console.log(typeof yourName); // > "function"

     

     

    Tip: 호이스팅 사용 시 주의

    - 코드의 가독성과 유지보수를 위해 호이스팅이 일어나지 않도록 한다.
    - var를 쓰면 혼란스럽고 쓸모없는 코드가 생길 수 있다

     

     

     

     

     

     

     

     

    출처: https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html

     

    728x90
    반응형

    댓글