[JavaScript]Hoisting & TDZ

박광민·2023년 3월 23일
0

Hoisting

  • 변수나 함수가 해당 스코프의 최상단으로 끌어올려진 것 같은 현상
    -> 동일한 스코프 내에서는 어디서든지 참조할 수 있다는 것을 말함

scope에 대한 사전지식

  • scope : 변수에 접근할 수 있는 범위
    -> var로 선언한 변수와 let 또는 const로 선언한 변수의 스코프는 다름
    • 블록 스코프 -> 중괄호 {}로 감싸진 범위
    • 함수 스코프 -> function(){}에서 중괄호 {} 내부의 범위
      -> 즉 함수 코드 블록 내부의 범위
  • 자바스크립트는 기본적으로 함수 스코프를 따름
    -> var로 변수를 생성할 시 함수 스코프 내에서 유효함
    -> but let, const로 변수를 생성할 시, 블록 스코프 내에서 유효함

호이스팅이 왜 일어날까?

  • 자바스크립트 변수생성과 초기화(선언과 할당)가 분리되어 진행되기 때문

JavaScript에 대한 사전지식

  • 자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언함
    • 자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑음
    • 함수 안에 존재하는 변수/함수 선언에 대한 정보를 기억하고 있다가 실행시킴
    • 유효 범위 -> 함수 블록 { } 안에서 유효
      -> 즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것
      -> 실제로 코드가 끌어올려지는 건 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것임
      -> 따라서 실제 메모리에서는 변화가 없음

왜 var를 쓰면 안좋을까?

  • var로 선언된 변수는 함수 스코프를 가짐
    -> hoisting(호이스팅) 발생
    -> 예상치 못한 동작 발생할 수 있음
function example() {
 console.log(x); // undefined
 var x = 17;
}

// 이 코드에서는 함수 안에서 x라는 변수를 선언하고 17로 초기화함
// 그리고 함수의 맨 위에서 x를 출력하려고 함
// but 그러나 실제로 출력되는 값 -> "undefined"
// -> 변수 x가 호이스팅되어 함수의 맨 위로 끌어올려졌기 때문
// -> 그래서 블록스코프를 가진 let이나 const로 변수 선언 하는 것이 좋음

변수는 어떻게 생성되고, 호이스팅은 어떻게 이뤄질까?

1단계: 선언 단계(Declaration phase)

  • 변수를 실행 컨텍스트의 변수 객체에 등록
    -> 이 변수 객체는 스코프가 참조하는 대상이 됨

2단계: 초기화 단계(Initialization phase)

  • 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보함
    -> 이 단계에서 변수는 undefined로 초기화됨

3단계: 할당 단계(Assignment phase)

  • undefined로 초기화된 변수에 실제 값을 할당됨
  • let, const를 사용해 변수를 생성할 시에는 3 단계가 각각 따로따로 이뤄짐
  • var 을 사용해 변수를 생성할 시에는 선언 단계와 초기화 단계가 한번에 이뤄짐
  • 함수 선언문을 사용할 시에는 세 단계가 한 번에 이뤄짐
    -> 선언, 초기화, 할당이 한 번에 이뤄짐
    -> 함수 전체가 스코프 최상단으로 호이스팅

TDZ

  • let, const을 사용하여 변수를 선언하였을 때, 해당 변수를 선언하기 이전에는 접근할 수 없는 구간을 의미함
    -> TDZ는 변수가 선언되기 전까지 변수를 사용하려 할 때 ReferenceError가 발생하게 됨 (어떠한 값도 가지지 않기 때문에)
    -> 즉, 변수가 선언되기 이전에는 접근할 수 없고,
    변수가 초기화된 이후에 사용할 수 있음

TDZ가 왜 필요한가?

  • Temporal Dead Zone은 변수의 스코프를 명확하게 하기 위한 것
    -> 이전에는 var 키워드를 사용하여 변수를 선언하면, 변수가 선언되기 이전에도 해당 변수에 접근할 수 있었으며, 값이 undefined로 할당되었음
    -> 이는 예기치 못한 동작을 일으킬 수 있는 위험이 있음
    -> 따라서 let과 const를 사용하여 변수를 선언하면, 변수가 선언되기 이전에는 해당 변수에 접근할 수 없으며, TDZ에 진입하게 됨
    -> 이렇게 함으로써 변수의 스코프를 더욱 명확하게 하고, 예기치 못한 동작을 방지할 수 있음
profile
developer(Frontend)

0개의 댓글