호이스팅과 TDZ

고먐미·2023년 3월 29일
0

스코프란?

식별자 접근 규칙에 따른 유효 범위

  • 식별자(변수,함수,클래스)에 접근할 수 있는 범위가 존재한다.
  • 범위는 중괄호(블럭) 또는 함수에 의해 나눠진다.
  • 이때, 이 범위를 스코프라고 부른다.
  • 그래서 각각을 Block ScopeFunction Scope 라고 부른다.

호이스팅

호이스팅이란?
자바스크립트에서 변수,함수 선언을 현재 스코프의 최상단으로 올려주는듯한 현상

  • 주의!
    호이스팅은 코드 실행 전 변수, 함수 선언을 현재 스코프의 최상단으로 끌어올리는 것이 아니라 끌어올려진 것 같은 현상이다.
  • 자바스크립트 엔진은 코드를 실행하기 전 실행 가능한 코드를 형상화하고 구분하는 과정을 거친다. (실행 컨텍스트를 위한 과정)
  • 또한, 코드를 실행하기 전 실행 컨텍스트를 위한 과정에서 모든 선언을 스코프에 등록한다. (var, let, const, function, class)
  • var 키워드로 변수나 함수를 선언할 시 코드 실행 전 이미 변수선언/함수선언이 저장되어 있기 때문에 선언문보다 참조/호출이 먼저 나와도 오류 없이 동작한다.

실행 컨텍스트란?
실핸 가능한 코드가 실행되기 위해 필요한 환경을 의미하고 실행되기 전 이런 실행 컨텍스트 과정(코드를 구분하는 과정)을 거친다.

변수 호이스팅

  • 자바스크립트의 모든 선언에는 호이스팅이 일어난다.
  • 그런데 let, const, class 를 이용한 선언문은 호이스팅이 발생하지 않는 것처럼 동작한다.
  • var 와 달리 let으로 선언된 변수를 선언문 이전에 참조하면 참조 에러가 발생한다. (Reference Error)
  • 이는 스코프의 시작에서 변수의 선언까지 일시적 사각지대(Temporal Dead Zone)에 빠지기 때문이다.

TDZ?

TDZ란?
선언 전 변수를 사용하는 것을 허용하지 않는 개념상의 공간이다.

  • var 는 선언과 동시에 undefined 로 값이 초기화 된다.
  • 하지만 let, const 는 선언과 초기화가 따로 이루어진다.
  • 이로인해 let, const 는 초기화되지 않은 상태에서 let, const 를 참조하게되면 참조에러가 발생한다.
  • 이를 TDZ 에러라고도 한다.

let 과 const 를 var 대신 사용해야 하는 이유
var 를 사용할 경우에는 호이스팅이 일어나면서 undefined가 뜨고 넘어갈 수 있다. 이는 내가 의도하지 않은 코드 진행이 일어나게 만들 수 있는데 만약 var가 아닌 let, const 를 사용하게 되면 참조에러가 뜨면서 이를 방지할 수 있다.
( let, const 도 호이스팅이 발생하긴 한다. 하지만 값이 초기화되지 않았기 때문에 참조에러가 뜨는 것 )
또한, TDZ를 통해 스코프가 확실하게 구분되고, 변수의 범위가 제한이 되니 코드의 가독성도 높아진다.


호이스팅이 뭔지 아시나요?
변수 선언이나 함수 선언이 끌어올려지는듯한 현상을 호이스팅이라고 합니다!

그렇다면 우리가 변수 선언을 할 때 var, let, const가 있는데, 이 var, let, const 가 호이스팅이 일어나면 어떤 현상이 발생하나요?
var 같은 경우에는 undefined 가 출력이 되고 let, const 같은 경우에는 reference error 가 뜹니다.

그렇다면 var는 왜 undefined가 뜨고 let, const 참조에러(reference error)가 뜨나요?
var 는 선언과 동시에 undefined로 값이 초기화 되기 때문에 할당이 되지 않은 상태에도 undefined 라는 값을 출력 할 수 있습니다.
하지만 let, const 같은 경우 선언과 초기화가 따로 이루어지기 때문에 초기화되지 않은 상태에서 let, const를 참조하려고 하면 참조에러(reference error)가 발생합니다. 이를 TDZ 에러라고도 합니다.

그렇다면 우리가 var 를 사용하다가 es6에 let, const 가 생겼는데, 이를 var 대신 사용하라고 권장합니다. 이 이유를 호이스팅과 연관시켜 답변해주실 수 있나요?
let, const 를 사용하면 예상치 못한 동작을 방지할 수 있기 때문입니다.
var 를 사용할 때에는 undefined가 뜨는 것을 보고 그냥 넘어갈 수 있어 내가 의도하지 않은 코드진행이 이뤄질수도 있지만 let, const를 사용하면 참조에러가 뜨면서 이를 방지할 수 있습니다.
( 또한, TDZ를 통해 스코프가 확실하게 구분이 되고 변수의 범위가 제한이 되니 코드의 가독성도 높아지기 때문입니다. )


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

https://velog.io/@jangwonyoon/%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85%EA%B3%BC-TDZ%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B4%EA%B3%A0-%EC%96%B4%EB%96%A4-%EC%97%B0%EA%B4%80%EC%9D%B4-%EC%9E%88%EC%9D%84%EA%B9%8C%EC%9A%94#-temporal-dead-zonetdz

profile
개념을 이해하고 다른사람에게도 알려줄 수 있는 개발자가 되고 싶어요..

0개의 댓글