[바미] Hoisting에 대해 알아보자!
Hoisting은 우리가 무의식적으로 사용하고 있을 수 있는 개념입니다. 이번 글에서는 Hoisting의 특징에 대해 알아보겠습니다.
모든 변수 선언은 호이스팅(Hoisting)되는데 호이스팅(Hoisting)이란 변수의 선언과 할당이 분리되어 처리되는 것을 의미합니다.
쉽게 말해서 변수가 함수 내부에서 선언되었을 경우 해당 선언은 함수의 최상위로 끌어올려지고, 함수 외부에서 선언되었을 경우 전역 컨텍스트의 최상위로 이동하게 됩니다.
이렇게 말로하는것보다 코드로 이해하는게 더 빠르니 코드를 봅시다.
const hoisting = () => {
console.log("First-Name:", name);
var name = "Marcus";
console.log("Last-Name:", name);
}
hoisting();
// First Name : undefined
// Last Name : Marcus
// First Name이 undefined인 이유는 지역변수 name이 호이스트 되었기 때문이다.
위 hoisting이라는 함수는 자바스크립트로 이해하면 다음과 같이 표현할 수 있습니다.
const hoisting = () => {
var name; // name 변수는 호이스트 되었습니다. 할당은 이후에 발생하기 때문에, 이 시점에 name의 값은 undefined 입니다.
console.log("First name : " + name); // First Name : undefined
name = "Marcus"; // name에 값이 할당 되었습니다.
console.log("Last Name : " + name); // Last Name : Ford
}
자! 그렇다면 let 과 const에서는 호이스팅이 될까요?
먼저 위에서 var로 작성한 hoisting이라는 함수를 let과 const로 바꿔보죠.
const hoisting = () => {
console.log("Name:", name);
let name = "Marcus";
}
hoisting();
// ReferenceError: name is not defined
먼저 let으로 했을 경우 name is not defined라는 에러가 발생합니다.
왜일까요? 앞서 설명했을땐 변수가 함수내에서 정의되었을 경우 선언이 함수의 최상위로, 함수 바깥에서 정의되었을 경우는 전역 컨텍스트의 최상위로 변경된다
라고 설명했었죠?
이 이유를 설명하려면 우리는 Temporal Dead Zone(TDZ)라는 개념을 알아야 합니다.
우선, TDZ(Temporal Dead Zone)에 대해 간단히 설명하고 넘어가겠습니다.
let과 const 선언은 기본적으로 실행 중인 실행 컨텍스트의 어휘적 환경(Lexical Environment)에 따라 변수를 정의합니다.
변수는 어휘적 환경에 포함될 때 생성되지만, 어휘적 바인딩이 실행되기 전까지는 접근할 수 없습니다. 새로운 스코프에 진입할 때, 해당 스코프에 속한 모든 let과 const 변수는 코드가 실행되기 전에 바인딩됩니다. (즉, let과 const도 호이스팅되지만, 다르게 동작합니다.)
이처럼 바인딩이 완료되기 전까지 변수를 사용할 수 없는 현상을 TDZ라고 부르죠.
쉽게 말하면 스코프에 진입하면서 변수가 생성되지만, 코드 실행이 변수가 선언된 위치에 도달할 때까지는 접근할 수 없다는 뜻입니다.
TDZ를 이해한바로 간단한 테스트 코드를 작성해보면
// const TDZ를 실행하기 전에 TDZ에 접근하면, TDZ에 의해 ReferenceError가
발생하게 된다.
// console.log(TDZ);
// output: ReferenceError: tdz is not defined
const TDZ = 'Temporal Dead Zone'
// 위 코드 실행 이후에는 TDZ에 접근할 수 있다.
console.log(TDZ);
// output: Temporal Dead Zone
결론
let과 const로 선언된 변수도 사실 호이스팅이 되지 않는 것은 아닙니다.
스코프에 진입할 때 변수가 생성되고 TDZ(Temporal Dead Zone)가 형성되지만, 변수 선언부에 도달하기 전까지는 해당 변수에 접근할 수 없을 뿐입니다.
따라서 변수가 선언된 시점에서 TDZ를 벗어나게 되고, 그 때부터 변수를 사용할 수 있게 되는 것이죠.