Just Do IT!

[JavaScript] 호이스팅(Hoisting)이란? (+ TDZ란) 본문

개발 공부/JavaScript

[JavaScript] 호이스팅(Hoisting)이란? (+ TDZ란)

MOON달 2023. 3. 28. 17:08
728x90

Hoisting (호이스팅)

  • 코드가 실행하기 전 변수선언/함수선언이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상
  • 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것
  • 자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아 유효 범위의 최상단에 선언한다
  • 자바스크립트의 모든 선언에는 호이스팅이 일어난다.
  • let, const, class를 이용한 선언문을 호이스팅이 발생하지 않는 것처럼 동작한다

 

 

 

 

var

  • 선언 단계와 초기화 단계가 한번에 이루어진다
  • 변수 선언문 이전에 변수에 접근하여도 스코프에 변수가 존재하기 때문에 에러가 발생하지 않는다. (undefined 반환)
console.log(text); // ReferenceError
text = 'Hello';
var test;
console.log(text); // "Hello"

 

 

let, const

  • 변수 선언과 함수 표현식에서는 호이스팅이 발생하지 않는다
  • 선언 단계와 초기화 단계가 분리되어 진행된다
  • 선언된 변수를 선언문 이전에 참조하면 참조 에러(ReferenceError)가 발생한다.

 

 

 

+) 변수의 생성 단계

1. 선언 단계 (Declaration phase)

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

2. 초기화 단계 (Initialization phase)

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

3. 할당 단계 (Assignment phase)

  • unefined로 초기화된 변수에 실제 값을 할당한다

 

 

 

 

 

 

 

 

 

 

TDZ (Temporal Dead Zone) 이란?

  • 구문(let, const, class 등)의 호이스팅으로 선언만 되고 초기화 되지 않은 지역을 의미
  • 호이스팅은 블록 단위로 발생하는데, 블록이 생성될 때 블록 안의 호이스팅으로 선언을 먼저 하게 되는데 선언 후 초기화되기 전까지 호이스팅 된 구문을 TDZ에 있다고 말한다
  • TDZ에 있는 구문을 호출하게 되면 초기화 되지 않았기 때문에 Reference Error 발생
  • var은 선언과 동시에 초기화가 이루어지기 때문에 var의 TDZ가 없다
  • TDZ에서 typeof 연산자를 사용하게 되면 Reference Error가 발생하게 된다
  • 선언되지 않은 변수에 typeof 연산자를 쓰면 결과는 undefined이다
{
	console.log(bar); // undefined
	console.log(foo); // ReferenceError
	var bar = 10;
	let foo = 2;
}

=> var은 TDZ가 없지만, let은 TDZ가 존재하기 때문에 Reference Error가 발생한다.

let a = 10;
if (true){
	console.log(a); // Reference Error
    	let a = 10;
}

=> 호이스팅이 블록 단위로 발생한다는 것을 알려준다

 

TDZ를 갖는 구문

  • const
  • let
  • class
  • constuctor() 내부의 super()
  • 기본 함수의 매개변수

var, function, import

  • 호이스팅 시 선언과 초기화가 같기 때문에 undefined로 초기화된다
  • function의 선언과 import도 호이스팅 되기 때문에 함수 선언을 어디에서 해도 호출될 때 문제가 없다

 

 

 

 

 

 

 

 

 

 

함수의 호이스팅

함수 선언문에서의 호이스팅

  • 코드를 구현한 위치와 관계없이 자바스크립트의 특징인 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어올려진다
function printName(firstName) { // 함수 선언문
	var result = inner(); // 선언 및 할당
	console.log(typeof inner); // function
	console.log("name is " + result);

	function inner() { // 함수 선언문
		return "inner value";
	}
}

printName();  // 함수 호출

 

함수 표현식에서의 호이스팅

  • 선언과 호출 순서에 따라서 정상적으로 함수가 실행되지 않을 수 있다
  • 선언과 할당의 분리가 발생한다
  • 함수 표현식의 선언이 호출보다 아래에 있는 경우(var) => typeError
  • 선언이 호출보다 아래에 있는 경우 (const/let) => ReferenceError
foo1(); // 함수 선언문에서는 호이스팅 일어난다.
foo2(); // 함수 표현식이라서 호이스팅 안된다. (TypeError)
function foo1() {
  console.log('Hello');
}
var foo2 = function() {
  console.log('world');
}

 

 

 

 

 

 

 

 

 

 

 

 


MDN 문서 읽기

https://developer.mozilla.org/ko/docs/Glossary/Hoisting

 

호이스팅 - MDN Web Docs 용어 사전: 웹 용어 정의 | MDN

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다

developer.mozilla.org

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#temporal_dead_zone_tdz

 

let - JavaScript | MDN

The let declaration declares a block-scoped local variable, optionally initializing it to a value.

developer.mozilla.org