자바스크립트

호이스팅

training center 2023. 4. 6. 21:40

호이스팅

자바스크립트에서 호이스팅이란 모든 선언을 메모리 공간에 미리 할당 하는것이다.

호이스팅 대상: ES6에서 도입된 let, const를 포함하여 모든 선언(var, let, const, function, function* , class)을 호이스팅한다.

var의 경우 메모리 공간에 할당되면서 undefined로 초기화 되지만 let과 const는 초기화 되지 않는다.

주의: 선언과 할당이 동시에 일어나면 호이스팅 되지 않는다.

—var 호이스팅

console.log(a); // undefined
var a;
a = 5;
console.log(a); // 5

주의 선언과 할당이 동시에 일어날 경우 할당은 호이스팅되지 않는다.

function hoisting() {
	alert(a) // undefined
	var a = "hi";
}

hoisting()

// 위 코드는 아래와 같이 실행된다.

function hoisting() {
	var a // 함수 시작과 동시에 선언만 호이스팅 됨.
	alert(a) // undefined
	a = "hi"; // 코드 흐름 순서에 따라 이 지점에서 a 에 문자열이 할당됨.
}

hoisting()

 

—let, const 호이스팅

console.log(a); // ReferenceError
let a;
let foo = 'a'

{
	console.log(foo) // ReferenceError
	let foo = 'b'
}

위의 두 예시에서 let 키워드는 에러를 띄워 마치 호이스팅이 되지 않는것 처럼 보인다.

스코프에 변수를 등록(선언단계)하지만 초기화 단계는 변수 선언문에 도달했을 때 이루어진다. 초기화 이전에 변수에 접근하려고 하면 참조 에러(ReferenceError)가 발생한다.

스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 ‘일시적 사각지대(Temporal Dead Zone; TDZ)’라고 부른다.

변수가 어떻게 생성되며 호이스팅은 어떻게 이루어지는지 좀 더 자세히 살펴보자. 변수는 3단계에 걸쳐 생성된다.

  1. 선언 단계
    1. 변수를 실행 컨텍스트 변수객체에 등록한다.
  2. 초기화 단계
    1. 변수객체에 등록된 변수를 위한 공간을 메모리에 확보한다. 이 단계에서 변수는 undefined로 초기화된다.
  3. 할당 단계
    1. undefined로 초기화된 변수에 실제 값을 할당한다.

 

—함수 호이스팅

foo1(); // 함수 선언문에서는 호이스팅 일어난다.
foo2(); // 함수 표현식이라서 호이스팅 안된다.

function foo1() {
  console.log('Hello');
}
var foo2 = function() {
  console.log('world');
}

 

TDZ

let foo = 'a' // 전역 변수

{
	console.log(foo) // ReferenceError
	let foo = 'b' // 지역 변수
}

위 예제에서 콘솔에 전역변수 값이 출력될것 처럼 보인다. 하지만 ES6의 선언문도 호이스팅이 발생되기 때문에 참조에러가 발생한다.

지역 변수 foo도 해당 스코프에서 호이스팅되고 코드 블록의 선두부터 초기화가 이루어지는 지점까지 일시적 사각지대(TDZ)에 빠진다. 따라서 전역 변수 foo의 값이 출력되지 않고 참조 에러(ReferenceError)가 발생한다.