2 분 소요

실행 컨텍스트 》에 이어 작성하는 글입니다.


▶ 호이스팅

호이스팅이란 선언된 변수나 함수 선언시 scope 내의 최상단으로 끌어올리는 것을 말한다. (레코드를 수집하는 과정이 호이스팅⭐)


  • 아래 코드는 어떻게 출력될지 생각해보자
console.log(a);
var a = 10;

js 코드는 인터프리터에 의해 한 줄씩 순차적으로 코드를 실행한다. 따라서 변수 a를 선언하기 전에 a를 출력하려고 하기 때문에 참조 에러가 발생하지 않을까?

❓ 하지만 참조 에러가 발생하지 않고 undefined가 출력된다! 왜 그럴까?

그 이유는 변수 선언이 런타임 전 단계에서 실행되기 때문이다!

이게 무슨 말이냐, 런타임은 프로그램이 실행되고 있는 동안의 동작을 말한다. 즉, 프로그램이 실행되기 전에 변수 선언이 이루어진다는 것이다!

❓ 어떻게 프로그램이 실행되기 전 변수 선언이 이루어질 수 있을까?

인터프리터 과정을 거치기 전 소스코드의 평가 과정을 거치기 때문이다.

  • 소스코드 평가 과정이란 변수 선언을 포함한 모든 선언문(변수, 함수 선언문 등)을소스코드에서 찾아내 먼저 실행한다. 이 과정이 끝난 후 코드를 순차적으로 실행하는 인터프리터 과정을 거친다.
  • 즉, js 엔진은 변수 선언이 소스 코드 어디에 있던 다른 코드보다 먼저 실행이 되기 때문에 변수 선언이 어디에 위치해있던 어디서든지 변수를 참조할 수 있는 것이다.

이처럼 코드 실행 전 변수나 함수를 찾아 스코프의 최상단으로 끌어올려주는 것을 호이스팅이라 말한다.

따라서 위 코드는 변수 a가 선언되기 전에 출력되었지만, 호이스팅으로 인해 변수 선언문이 스코프의 최상단으로 이동되기 때문에 에러가 발생하지 않고 undefined가 출력된다.




▶ 호이스팅 규칙

  1. 매개변수 및 변수는 선언부를 호이스팅 한다.
  • 적용 전
function a(x) {
  console.log(x);
  var x;
  console.log(x);
  var x = 2;
  console.log(x);
}
a(1);


  • 매개변수 적용
function a() {
  var x = 1;
  console.log(x); // 1
  var x;
  console.log(x); // undefind
  var x = 2;
  console.log(x); // 2
}
a(1);


  • 호이스팅 적용
function a() {
  var x;
  var x;
  var x;

  x = 1;
  console.log(x); // 1
  console.log(x); // 1
  x = 2;
  console.log(x); // 2
}
a(1);

➡️ 실행 결과를 1 → undefined → 2로 예상했지만, 실제로 1, 1, 2 라는 결과가 나왔다. ➡️ 이는 호이스팅이 적용되었기 때문!


  1. 함수 선언은 전체를 호이스팅한다.
  • 적용 전
function a() {
  console.log(b);
  var b = "bbb";
  console.log(b);
  function b() {}
  console.log(b);
}
a();


  • 호이스팅 적용
function a() {
  var b; // 변수 선언부 호이스팅
  function b() {} // 함수 선언은 전체를 호이스팅

  console.log(b); // [Function: b] 출력

  b = "bbb"; // 변수의 할당부는 원래 자리에

  console.log(b); // bbb 출력
  console.log(b); // bbb 출력
}
a();




▶ 함수 선언문과 표현식의 호이스팅

  • 함수 선언문과 표현식에 대한 자세한 내용은 《 함수 》을 참고하자.

함수 선언문

  • function 키워드를 사용하여 함수를 선언하는 방식을 말한다.
  • 함수 선언문은 함수의 최상위로 호이스팅된다. 따라서 함수가 선언되기 전에 호출할 수 있다.
console.log(add(3, 2)); // 5

function add(x, y) {
  return x + y;
}


함수 표현식

  • 변수에 함수를 할당하는 방식을 말한다.
  • 함수 표현식은 변수 선언 이전에 호출하면 에러가 발생한다.
  • 함수 표현식으로 함수를 정의하면 함수 호이스팅이 발생하는 것이 아니라 변수 호이스팅이 발생한다.
    • 즉, 변수 부분만 호이스팅 되는 것이다.
console.log(result(3, 2)); // TypeError

var result = function (x, y) {
  return x + y;
};


  • 적용 전
console.log(sum(1, 2));
console.log(multiply(3, 4));

function sum(a, b) {
  // 함수 선언문 sum
  return a + b;
}

var multiply = function (a, b) {
  // 함수 표현식 multiply
  return a + b;
};


  • 적용 후
// 함수 선언문은 전체를 hoisting
function sum(a, b) {
  // 함수 선언문 sum
  return a + b;
}

// 변수는 선언부만 hoisting

var multiply;

console.log(sum(1, 2));
console.log(multiply(3, 4));

multiply = function (a, b) {
  // 변수의 할당부는 원래 자리
  return a + b;
};

➡️ 협업을 많이하고 복잡한 코드일수록, 전역 공간에서 이루어지는 코드 협업일 수록, 함수 표현식을 활용해야 한다!!




📎참조

TDZ(Temporal Dead Zone)이란?

댓글남기기