
📌 "호이스팅(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도 호이스팅이 일어난다.