그림 그리는 개발자
  • 호이스팅 (hoisting) (2)
    2023년 07월 22일 21시 01분 54초에 업로드 된 글입니다.
    작성자: 루루개발자

    안녕하세요. 루루개발자 입니다.

    프론트엔드 개발을 하다보면 한번쯤은 들어봤을 법한 단어가 있습니다. 바로 "호이스팅" 입니다. 사실 이 호이스팅에 대한 글을 이전에 한번 올린적이 있는데 좀 더 세부적으로 작성하고 만화로 설명한 부분도 추가한 버전으로 재작성하여 올려보게 되었습니다.

     

    호이스팅이란?

    호이스팅은 간단하게 설명하면 "코드가 실행되기 전에 변수 선언 부분이 최상단으로 끌어 올려지는 현상" 이라고 말해볼 수 있습니다. 하지만 이를 좀 더 자세히 설명하면 "자바스크립트 엔진이 각각의 스코프들을 하나씩 돌면서 해당 스코프안에 선언된 정보들을, 코드를 실행하기 전에 미리 수집하는 현상" 이라고 말해볼 수 있습니다. 즉, 코드를 실행하기 전에 어떤 변수들이 선언 되었는지 미리 수집하였고 그렇기에 미리 알고 있는 상태이기 때문에 코드가 실행되었을 때 선언전 위치에서 변수를 참조하는 것이 가능하게 됩니다. 하지만 호이스팅이 되는 범위가 항상 동일하지는 않습니다. 이 내용은 바로 아래에 기술합니다.

     

    function, var, let & const 각각 호이스팅이 되는 범위가 다르다!

    javascript 에서 사용되는 function, var, let, const 키워드 모두 호이스팅이 되지만 어디까지 호이스팅이 되는지에 대한 차이가 존재합니다. 호이스팅에 대한 차이를 설명 드리기 전에 먼저 변수의 3단계에 대해 알아보겠습니다. 변수는 "선언", "초기화", "할당" 순으로 동작하게 됩니다. 이를 염두에 두시면서 아래 내용을 확인하시면 좋습니다.

    • function : 해당 키워드는 "선언", "초기화", "할당" 이 한 단계에서 모두 진행되며 선언부터 할당까지 모두 호이스팅이 됩니다. 그렇기 때문에 function 으로 선언한 함수는 선언전 위치에서 호출해도 선언된 내용이 정상적으로 동작합니다.
    • var : 해당 키워드는 "선언", "초기화" 가 한 단계에서 모두 진행되며 선언과 초기화까지만 호이스팅이 됩니다. 즉 할당 부분은 호이스팅이 되지 않습니다. 초기화 될 때 undefined 로 초기화가 되므로 선언 전 위치에서 해당 변수를 참조하게 되면 undefined 로 참조되게 됩니다.
    • let & const : 해당 키워드들은 "선언", "초기화", "할당" 이 각각의 단계에서 진행되며 선언 부분만 호이스팅이 됩니다. 즉, 초기화와 할당 부분은 호이스팅 되지 않습니다. 그렇기 때문에 선언 전 위치에서 해당 변수를 참조하게 되면 초기화가 되기전에 참조가 되었기 때문에 초기화 관련 에러가 발생하게 됩니다.
    let 과 const 는 선언전 위치에서 참조하게 되면 에러가 발생하여 let 과 const 는 호이스팅이 되지 않는다고 생각할 수도 있습니다. 하지만 let 과 const 도 호이스팅은 됩니다. 선언 전 위치에서 let 이나 const 로 선언된 변수를 참조하였을 때 표시되는 에러메시지를 자세히 보시면 "Uncaught ReferenceError: Cannot access '변수명' before initialization" 라는 에러가 표시됩니다. 즉, 엔진은 해당 변수의 존재 자체는 인지하고 있다는 말이 되며 이는 호이스팅이 되었기 때문에 가능한 현상입니다. 단지 에러가 표시되는 이유는 let 이나 const 는 변수의 선언 부분까지만 호이스팅이 되며 초기화~할당 부분에 대한 정보는 호이스팅이 되지 않기 때문에 선언전 위치에서 변수를 참조하게 되면 초기화가 되기 전에 참조가 진행되었기 때문에 본 에러가 발생하게 되는 것입니다.
    여기서 TDZ(Temporal Dead Zone) 개념도 같이 설명이 가능합니다. TDZ 는 변수의 선언이 시작된 지점과 초기화 되기까지 사이의 구간을 일컫습니다. 즉, 선언은 되었는데 아직 초기화가 되기 전 상태를 말합니다. 이런 상태인 TDZ 에서 변수가 참조되면 초기화가 되기 전에 참조가 진행되었다는 에러가 발생하게 됩니다. function 이나 var 키워드 같은 경우는 변수의 선언과 초기화가 한 단계에서 동시에 진행되기 때문에 TDZ 가 없습니다. 그러므로 이 둘 키워드는 TDZ에 영향을 받지 않는다고 말해볼 수 있으며, let 이나 const 키워드 같은 경우는 변수의 선언과 초기화가 별개의 단계로 진행 되므로 TDZ 가 존재한다고 할 수 있고 TDZ 에 영향을 받는다고 말해볼 수 있습니다.

     

    그래도 이해가 잘 안가시는 분들을 위해 만화로 표현해봤습니다!

    아래와 같은 javascript 코드를 엔진이 실행해야 하는 상황이라고 가정한 만화입니다.

    console.log('timestamp', getTimestamp());
    console.log('age', age);
    console.log('name', name);
    
    const name = '홍길동';
    var age = 27;
    function getTimestamp() {
      return Date.now();
    }

     

     

    이상으로 호이스팅에 대해 작성해보았습니다.

    도움이 되셨으면 좋겠습니다. :)

    감사합니다.

     


     

    - 출처 - 

    https://tecoble.techcourse.co.kr/post/2021-04-25-hoisting/
    댓글