Hoisting이란? TDZ란?

SB22·2023년 3월 28일

기술면접준비

목록 보기
3/15

Hoisting과 TDZ는 무엇일까 ?

스코프, 호이스팅, TDZ

1. 스코프(Scope)

  • 자바스크립트에서 스코프는 변수의 유효범위이다.
  • 안쪽 스코프에서 바깥쪽 스코프로 접근이 가능하지만 반대로 바깥쪽에서 안쪽으로 접근이 불가능하다.
  • 중첩이 가능하다.
  • 바깥쪽 스코프는 전역 스코프(Global Scope)라고 불리고 전역 스코프가 아닌 다른 스코프는 전부 지역 스코프(local scope)이다.
  • 지역 변수는 전역 변수보다 더 높은 우선순위를 가진다.

1-1. 전역스코프(전역변수)와 지역스코프(지역변수)

  • 전역스코프는 코드 어디서든 가지고와서 사용할 수 있지만 지역스코프는 함수 자신과 하위 함수에서만 사용이 가능하다.
var a = 1;
//전역 스코프
console.log(a); //1 출력

function num () {
	var a = 2;  //a를 2로 다시 선언
//지역 스코프
console.log(a); //2 출력
}
console.log(a); //함수에서 나왔으므로 1 출력

1-2. 함수스코프

  • 자바스크립트는 기본적으로 함수 스코프를 따르는 언어이다.
  • 함수스코프를 따른다? => 새로운 함수가 생성될때마다 새로운 스코프가 발생한다.
    • 함수 몸체에 선언한 변수는 해당 함수 안에서만 접근할 수 있다. (부모스코프는 자식스코프에 간섭할 수 없다.)
  • 함수스코프 -> 지역스코프

1-3. 블록스코프

  • 블록{}이 생성이 될때마다 새로운 스코프가 형성된다.
  • 원래 자바스크립트는 함수 스코프를 따르지만, letconst 키워드의 등장으로 블록 스코프를 형성하는 것도 가능해졌다.

2. 호이스팅(Hoisting)

함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말한다.

  • 자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.
    • 자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는다.
    • 함수 안에 존재하는 변수/함수선언에 대한 정보를 기억하고 있다가 실행시킨다.
    • 유효 범위: 함수 블록 {} 안에서 유효
  • 즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것이다.
    • 실제로 코드가 끌어올려지는 건 아니며, 자바스크립트 Parser 내부적으로 끌어올려서 처리하는 것이다.
    • 실제 메모리에서는 변화가 없다.
  • var 변수 선언과 함수선언문에서만 호이스팅이 일어난다.
    • var 변수/함수의 선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다.
    • let/const 변수 선언과 함수표현식에서는 호이스팅이 발생하지 않는다.
  • 메모리에 미리 할당하는 것을 의미한다.
  • 자바스크립트에서 호이스팅은 예측하지 못할 결과를 초래할 가능성이 존재하기 때문에 지양하는 분위기이다.

3. TDZ(Temporal Dead Zone, 일시적 사각지대)

var 키워드와 달리 letconst 키워드를 사용하면 같은 식별자로 변수를 선언할 수 없다. 또한 undefined 로 초기화 되지 않기 때문에 선언하기 전에 변수를 사용하면 오류가 발생한다. 이 지점을 TDZ(Temporal Dead Zone)이라 부르기도 한다.

4. 함수 선언문과 함수 표현식에서 호이스팅 방식의 차이

4-1 함수 선언문(Function Declaration)

일반적인 프로그래밍 언어에서의 함수 선언과 비슷한 형식이다.
함수의 선언문을 통해 선언된 함수는 코드를 구현한 위치와 관계없이 자바스크립트의 특징인 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어 올려진다. 따라서 호이스팅에 영향을 받는다고 할 수 있다.

function 함수명() {
  구현 로직
}

4-2 함수 표현식(Function Expression)

유연한 자바스크립트 언어의 특징을 활용한 선언 방식이다. 이름이 없는 함수를 만들고, 변수를 선언해서 함수를 할당하는 경우를 말한다. 함수 선언문과 실행방식이나 동작방식은 동일하나, 선언과 호출 순서에 따라서 정상적으로 함수가 실행되지 않을 수 있다. 따라서 호이스팅에 영향을 받지 않는다.

let 함수명 = function () {
  구현 로직
};

5. let, const, var, function의 실행 원리

5-1. 재선언 가능 유무

  • 재선언 가능 : var

  • 재선언 불가능 : let, const

5-2. 재할당 가능 유무

  • 재할당 가능 : var, let

  • 재할당 불가능 : const

5-3. 함수스코프 vs 블록스코프

  • 함수스코프(function) : var

  • 블록스코프({}) : let, const

5-4. 호이스팅 가능 유무

  • 호이스팅 가능 : var, fuction

  • 호이스팅 불가능 : let, const

사실 let, const도 내부적으로는 모두 호이스팅 된다. 그러나 자바스크립트 내부에 TDZ라는 (개념)영역이 존재하며 TDZ 영역에 존재하는 변수는 접근이 불가능한데, 실제 변수 선언이 실행되는 구문이 실행되기 전에는 const, let, class로 선언된 이름은 모두 TDZ에 존재하여 참조 에러를 발생시키는 것이다.

0개의 댓글