호이스팅(Hoisting)

1TBhard·2020년 11월 7일
1

FrontEnd면접

목록 보기
1/7
post-thumbnail

📌 "호이스팅(Hoisting)"에 대해서 설명하세요."


호이스팅?

호이스팅 (Hoisting )이란 선언들을 모두 끌어 올려서 유효 범위(현재 선언된 지역)의 최상단에 선언되는 것을 말한다.

호이스팅의 대상변수 선언함수 선언문 이다.


변수의 호이스팅

변수는 호이스팅의 대상이며 var 혹은 let, const 를 사용하여 선언할 경우 아래와 같은 차이가 있다.

1. 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" 출력

2. const, let의 호이스팅

const, let호이스팅이 일어난다.
그러나, const, let 으로 선언한 변수를 선언 전에 출력하면 에러가 발생한다.

호이스팅에도 불구하고 에러 발생하는 이유는 const, letTDZ에 의해 제약을 받기 때문이다.

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도 호이스팅이 일어난다.
    • 그러나 TDZ에 제약을 받기 때문에 선언 전에 값을 변경하는 경우 에러가 발생한다.


참조

profile
기억을 넘어 습관으로

0개의 댓글