📌 "호이스팅(Hoisting)"에 대해서 설명하세요."
호이스팅 (Hoisting )이란 선언들을 모두 끌어 올려서 유효 범위(현재 선언된 지역)의 최상단에 선언되는 것을 말한다.
호이스팅의 대상은 변수 선언과 함수 선언문 이다.
변수는 호이스팅의 대상이며 var
혹은 let
, const
를 사용하여 선언할 경우 아래와 같은 차이가 있다.
var
의 호이스팅console.log(string); // 선언 전에 출력, myString 이 출력될까?
var string = "myString"; // 출력 후에 선언
if(true)
var text = "I show you"; // if 블록 안에 선언
console.log(text); // 과연 출력이 될까?
개발자가 위의 코드를 짜더라도 이는 JS의 호이스팅으로 인해 아래와 같이 바뀌게 된다.
// 호이스팅으로 인해 유효 범위의 최상단으로 끌려옴
var string
var text;
console.log(string); // 에러는 뜨지 않으나 undefined 출력
string = "myString"; // 이때 string에 "myString" 이 들어감(치환됨)
if(condition)
text = "I show you";
console.log(text); // "I show you" 출력
const
, let
의 호이스팅const
, let
도 호이스팅이 일어난다.
그러나, const
, let
으로 선언한 변수를 선언 전에 출력하면 에러가 발생한다.
호이스팅에도 불구하고 에러 발생하는 이유는 const
, let
은 TDZ에 의해 제약을 받기 때문이다.
console.log(a);
const a = 10; // Uncaught ReferenceError: Cannot access 'a' before initialization
console.log(b);
let b = 5; // Uncaught ReferenceError: b is not defined
💡 TDZ(Temporal Dead Zone ) : 초기화 되지 않은 변수가 있는 공간이다.
var
,function
은 선언과 동시에 초기화가 되어 TDZ가 없다.
var
은 선언과 동시에undefined
로 초기화function
은 선언과 호이스팅 되어서 선언부분 자체가 올라감
let
,const
는 선언과 초기화가 분리되어 있다. 선언과 초기화 사이의 공간이 TDZ라고 한다.
- TDZ에서 변수를 호출하는 경우 참조에러가 발생한다.
let num = 1; var str = "hi"; function example() { // let은 블록스코프를 가지므로 전역변수 num이 아닌 지역 변수 num을 참조함 // 따라서, TDZ에 의해 참조 에러 발생 // console.log(num); console.log(str); // var은 TDZ에 영향이 없음, "hi" 출력 let num = 5; // 초기화되는 곳, TDZ 벗어나게됨 } example();
함수 선언문도 호이스팅의 대상이다. 따라서, 같은 유효 범위 내에서 함수를 어디서든지 호출할 수 있게된다.
hello();
function hello() {
console.log("hi");
}
호이스팅이 일어나면 아래와 같이 된다.
// 호이스팅으로 인해 위로 끌려와짐
function hello() {
console.log("hi");
}
hello(); // "hi" 출력
⚠️ 함수 표현식(함수를 변수에 넣어 선언)의 호이스팅은 함수가 아닌 변수로 인식하여 에러가 발생한다.
// 이와 같은 코드가 있는 경우 myFunction(); var myFunction = function () { console.log("heollo"); }
// 호이스팅에 의해 올라오지만 myFunction 은 변수로 선언되기 때문에 에러가 발생 var myFunction; // Uncaught TypeError: myFunction is not a function myFunction(); var myFunction = function () { console.log("heollo"); }
const
, let
도 호이스팅이 일어난다.