Javascript/core

hoisting과 TDZ

student513 2020. 12. 14. 15:07

var의 경우

console.log(a());
console.log(b());
console.log(c());

function a() {
	return 'a';
}

var b = function bb() {
	return 'b';
}

var c = function() {
	return 'c';
}

이 코드는 자바스크립트의 hoisting에 의해 다음과 같이 해석된다

function a() {
	return 'a';
}

var b;
var c;

console.log(a());
console.log(b());
console.log(c());

b = function bb() {
	return 'b';
}

c = function() {
	return 'c';
}

어째서 변수에 함수가 할당이 되는지에 관해서는 일급함수에 대해 알아보도록 하자

 

호이스팅 검증

다음 코드에서 inner()함수의 console.log는 undefined를 출력한다. 

왜일까?

var a = 1

function outer() {
	console.log(a); // 1
	function inner() {
		console.log(a); // undefined
		var a =3;
	}
	inner();
	console.log(a); // 1
}

outer();
console.log(a); // 1

hoisting에 의해 다음과 같은 코드로 해석되기 때문이다.

function inner() {
	var a;
	console.log(a); // undefined
	a = 3;
}

var의 호이스팅은 두 단계로 실행된다.

  1. 변수명만 위로 끌어올리고,
  2. undefined를 할당한다.

let, const의 경우

if(true) {
    let a = 10;
    if(true) {
        console.log(a) // Uncaught ReferenceError: Cannot access 'a' before initialization
        const a = 20;
    }
    console.log(a) 
}
console.log(a) 

첫 번째 console.log(a)에서 hoisting은 일어났다.

(만약 일어나지 않았더라면 상위 스코프의 let a=10로부터 10을 출력했어야한다.)

 

그런데 RefenceError가 발생했다는 것은 const a = 20을 인지했다는 의미이다.

대신 var와는 다르게 1단계만 실행된 것이다.

  1. 변수명만 위로 끌어올리고,

이를 TDZ(Temperal Dead Zone)이라 부른다. 

직역하면 임시사망지대겠지만 임시사각지대라고 흔히들 번역하는데, 

const, let에 대하여 실제로 그 위치에 선언된 변수까지 도달하기 전에는 해당 변수를 호출할 수 없다는 것이다

 

hoisting은 분명 일반적인 코드의 작동방식은 아니다. 그렇기에 에러의 발생 가능성이 있고,

ES6에서는 좀 더 언어적 차원에서 프로그래머의 실수에 의해 발생하는 에러를 막으려는 노력이 보인다.

 

(현업에서는 메인함수에 종속된 유틸함수들을 아래쪽에 선언하여 가독성을 증진시키려는 목적에서 hoisting을 사용하기도 한다.)

 

출처: Javascript 핵심 개념 알아보기 - JS Flow, 정재남 강사님, 코어자바스크립트