ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 호이스팅, 호이스팅 원인, 호이스팅 종류
    CS지식 2023. 11. 5. 14:30

    첫 콘솔을 보면 var는 undefined가 찍힌다.
    이처럼 선언 라인 전에도 변수를 참조할 수 있는 현상을 '호이스팅' 이라고 한다.

     

    var 키워드는 선언과 함께 undefined로 초기화되어 메모리에 공간을 확보한다.
    let과 const 키워드는 선언만 되고 초기화되지 않은 상태로 선언만 환경레코드(메모리)에 등록된다. (선언 라인에 도달하기 전에는 메모리에 공간을 확보하지 못한다.)

     

    자바스크립트의 모든 선언에는 호이스팅이 일어나지만 let, const를 이용한 선언문을 호이스팅이 발생하지 않는 것처럼 동작한다.
    let, const 키워드로 선언된 변수를 선언문 이전에 참조하면 참조 에러(ReferenceError)가 발생하는데
    이는 let과 const에도 호이스팅이 일어나기 때문에 에러를 일으키는 것이다.

     

    let, const 키워드로 선언된 변수는 스코프의 시작에서 변수를 위한 메모리 공간이 확보되기(초기화 단계)까지 일시적 사각지대(Temporal Dead Zone; TDZ)에 빠진다.

     

    - 원인

    자바스크립트 엔진이 먼저 전체 코드를 스캔하면서 변수같은 정보를 실행컨텍스트의 환경레코드에 미리 등록해놓는다.

    환경레코드: 식별자와 식별자에 바인딩된 값을 기록해두는 객체

     

    - 변수는 어떻게 생성될까?

    변수는 3단계에 걸쳐 생성된다. (선언: 실행컨텍스트의 레코드에 등록 → 초기화: 메모리 공간 확보 → 할당)

    1. var

    var는 선언과 초기화가 한번에 이루어진다.
    즉, 스코프에 변수를 등록하고 메모리에 변수를 위한 공간을 확보한 후, undefined로 초기화한다.
    따라서 변수 선언문 이전에 변수에 접근하여도 스코프에 변수가 존재하기 때문에 에러가 발생하지 않는다.
    다만 undefined를 반환한다. 이후 변수 할당문에 도달하면 비로소 값이 할당된다.

    2. const, let

    const, let은 선언과 초기화가 따로 이루어진다.
    즉, 스코프에 변수를 등록하지만 초기화 단계는 변수 선언문에 도달했을 때 이뤄진다.
    초기화 이전에 변수에 접근하려고 하면 참조 에러가 발생한다.
    변수를 위한 메모리 공간이 아직 확보되지 않았기 때문이다.
    따라서 스코프의 시작 지점부터 초기화 시작 지점까지는 변수를 참조할 수 없다.
    스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 ‘일시적 사각지대(Temporal Dead Zone; TDZ)’라고 부른다.

     

    - 호이스팅 종류

    1. 변수 호이스팅 (var VS const, let)

    - var 호이스팅 

    변수를 생성할 때, 환경레코드에 선언과 초기화를 동시에 한다. 그래서 선언 라인 전에 접근해도 undefined가 찍힌다.

     

    - const, let 호이스팅 

    변수를 생성할 때, 선언만하고 초기화는 하지 않는다. 그래서 선언 라인 전에 접근(참조)하면 Reference Error가 발생한다.

     

    - 일시적 사각지대

    let, const로 선언한 식별자는 선언 라인 이전에 참조할 수 없는데, 이 구역을 '일시적 사각지대'라고 부른다.

    즉, var는 선언과 초기화가 동시에 이루어진다.
    let, const는 선언만하고 초기화는 하지 않는다. 그래서 선언 라인 전에는 변수를 참조할 수 없다.

    2. 함수 호이스팅: 함수 표현식(var VS const, let), 함수 선언문

    - 함수 표현식 

    : 함수를 변수에 담을 수 있다. 변수 호이스팅과 동일하게 동작한다.

     

    (1) var 함수 표현식: 선언문 이전에 실행하려고 하면 환경레코드에 메모리 공간이 확보되어 있는 값이 undefined이고 undefined라는 데이터 타입은 함수와 달리 호출될 수 없어서 타입에러가 발생한다.

     

    (2) const, let 함수 표현식: 아직 환경레코드에 메모리 공간이 확보되어 있는 값이 없어 Reference Error가 발생한다.

     

    - 함수 선언문

    : 선언과 동시에 함수가 생성되어 선언 전에도 함수를 사용할 수 있다.

    : 선언과 동시에 완성된 함수 객체를 생성해서 환경레코드에 메모리 공간이 확보한다. 함수가 에러없이 실행된다. 그래서 사용을 지양해야한다!!!

     

    - 함수 표현식과 함수 선언문의 차이점

     

    1. 함수 표현식은 var 키워드 일 때는 환경레코드의 값을 undefined로 초기화해두는데 undefined를 호출하려해서 Type Error가 나고, let&const 일 때는 환경레코드에 값을 초기화해두지는 않아서 참조하려니까 Reference Error가 난다.

     

    2. 함수 선언문은 선언과 동시에 함수 생성을 마치고 온전히 환경레코드에 메모리 공간을 확보해서 저장해두기에 선언 라인 전에도 함수를 호출할 수 있다.

     


    참고
    - 하나몬님: https://hanamon.kr/javascript-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85%EC%9D%B4%EB%9E%80-hoisting/

     

    [JavaScript] 호이스팅(Hoisting)이란? - 하나몬

    ❗️호이스팅이란? 호이스팅은 코드를 실행하기 전 변수선언/함수선언을 해당 스코프의 최상단으로 끌어올리는 것이 아니다. 호이스팅은 코드가 실행하기 전 변수선언/함수선언이 해당 스코프

    hanamon.kr

    - 테코콕 하루님 : https://youtu.be/EWfujNzSUmw?si=ICfUnYVPczB2HqTh

     

    댓글

Designed by Tistory.