본문 바로가기

2주차

호이스팅(hoisting) 에 관하여

 

 

안녕하세요. YB 김고은입니다

오늘은 JS에서의 호이스팅에 대해서 다뤄보고자 합니다 

 

변수나 함수의 선언 위치가 코드에 어떤 영향을 미치는지 알기 위해서 호이스팅을 공부하는건 

필! 수! 라고 생각하기 때문에 이번 기회에 다시 복습해봅시다 ~

 

📍  호이스팅(hoisting) 이란 무엇인가? 

호이스팅이란 인터프리터가 코드를 실행하기 전, 함수/변수/클래스 또는 임포트의 선언문을
해당 범위의 맨 위로 끌어올리는 것처럼 보이는 현상을 뜻한다.

[MDN hoisting](https://developer.mozilla.org/ko/docs/Glossary/Hoisting)

 

 

단어 뜻 그대로, "위로 끌어 올리다" 라는게 포인트인데, 

변수나 함수 등의 선언을, js 엔진이 스코프의 최상단으로 끌어올리는 것 처럼 처리하는 동작 방식이다! 

그래서 변수나 함수를 선언하기 전에, 사용할 수 있는 것처럼 보이는 현상이 발생하는 이유가 바로 이 때문이라고 할 수 있다

 

다만, 위로 끌어올려지는 것은 선언 부분뿐이며,  값의 할당은 호이스팅 대상이 아니다. ❌

 

이번 포스트에서는 "함수 호이스팅"과, "변수 호이스팅"에 대해서 다뤄보겠다.

 

📍  함수 호이스팅

함수는 선언 방식에 따라 호이스팅의 방식이 나뉘는데, "함수 선언식"과 "함수 표현식" 순으로 살펴보자

 

1️⃣ 함수 선언식 

결론부터 말하자면, 함수 선언식(Function declarations) 호이스팅 된다! 그래서 선언 자체가 최상단으로 끌어올려져서(호이스팅되었다는 뜻) 선언 이전에도 호출이 가능하다. 그 예시는 다음과 같다.

 

Ishoisted(); // 결과값: '호이스팅 완전 뿌시기 ~ '

function Ishoisted () {
  console.log('호이스팅 완전 뿌시기 ~ ');
}

 

그렇다면 함수 표현식 예제를 통해 둘을 비교해보자.

 

2️⃣ 함수 표현식 

함수 표현식(Function expressions)은 변수에 함수를 할당해주는 방식인데, 함수 선언식과는 달리 호이스팅 되지 않는다

 

ishoisted(); // TypeError: ishoisted is not a function

var ishoisted = function() {
  console.log('호이스팅 ~~');
};

 

 

물론 함수 표현식과 함수 선언식을 조합하여도 호이스팅이 되지 않는 것을 볼 수 있다.

ishoisted(); // TypeError: ishoisted is not a function

var ishoisted = function example () {
  console.log('호이스팅 ~~');
};

 

 

📍 변수 호이스팅 

자바스크립트에서는 변수 생성이 선언 -> 초기화 -> 할당, 이렇게 3단계에 걸쳐서 이루어진다. 

이 과정을 토대로 언제 호이스팅이 이루어지고, 또 어떤 결과를 불러오는지 알아보고자 한다. 

 

변수 선언자는 var let const 가 쓰이는데, 순서대로 예제 코드를 통해서 호이스팅이 어떻게 작동하는지 살펴보자 

 

1️⃣ var 선언자 

var는 선언과 동시에 초기화가 이루어지며, 이 단계에서 호이스팅이된다. 하지만, 할당까지는 이루어지지 못하기 때문에 변수에는 undefined가 할당된다. 

 

console.log(hoist); // 결과: undefined
var hoist = 10;
console.log(hoist); // 결과: 10

 

위처럼, 1번 라인은 호이스팅으로 인해, undefined 가 찍히게 된다. 

 

 

2️⃣ let 과 const 선언자 

"아! var와 반대로 let과 const 는 호이스팅 안되겠구나"라고 생각한다면 큰 오산이다 

let과 const 역시, 호이스팅되지만, var와는 달리 TDZ(일시적 사각지대)에 놓인다는 점에서 다른 결과를 불러온다!

TDZ는 선언 이후부터, 초기화 전까지 변수의 접근을 막아주는 역할을 한다. 

따라서 변수에 접근하게 되면, ReferenceError를 뱉게 된다. 

console.log(hoist); // ReferenceError: Cannot access 'hoist' before initialization
console.log(hoist2); // ReferenceError: Cannot access 'hoist2' before initialization
let hoist = 10;
const hoist2 = 10;

 

TDZ 덕분에, 선언의 위치로 인한 예상치 못했던 논리적 오류를 막을 수 있기 때문에 

var 의 사용을 지양하고, let 과 const를 사용하기도 한다!  

 

 

지금까지 호이스팅의 개념과, 함수 그리고 변수에서 호이스팅이 동작하는지의 여부와, 호이스팅이 된다면 어떻게 동작되는지를 살펴봤다. 

js를 공부를 통해, 선언 순서를 고려하여 호이스팅으로 인해 예상치 못한 부작용을 방지할 수 있도록 해보자! 👋