Javascript

Javascript - 호이스팅에 관하여

보오 2022. 5. 1. 14:13

자바스크립트에서 함수 호이스팅이란?

 

함수를 먼저 실행시키고 함수선언문(Function Declarations)을 나중에 작성해도 자바스크립트에서 해당 함수를 실행시킬 수 있는 것.

 

함수선언문(Function Declarations) - fucntion MyFunc(){} 형태의 함수 선언문
함수표현식(Function Expressions) - 변수에 함수를 할당하는 방식(JS의 유연한 특성)

→ JS 컴파일 시점에 나중에 선언된 함수에 대한 메모리를 할당해놓은 상태이기 때문에, 실행 시점에 선언된 함수의 식별자 정보를 이미 알고 있음.

 

 

정확히 말하면 자바스크립트는 함수만 호이스팅 할 수 있는게 아니라 변수까지 호이스팅 가능하다.

 

그 전에 자바스크립트가 변수를 할당하는 과정을 알아야 한다.

 

 

자바스크립트가 변수를 할당할 때 < 선언 → 초기화 → 할당 >의 과정을 거친다.

선언: 파싱 과정에서 변수 객체가 변수에 대한 식별자들을 수집하는 일
*초기화: 식별자에 메모리를 할당하고 undefined 상태를 부여함
할당: 변수 안에 직접 값을 넘겨줌

 

위 과정에 의해 var, let, const 호이스팅에 차이점이 발생한다.

 

  • 선언된 함수는 상단에서 참조, 호출이 가능하다.
  • 선언된 var는 상단에서 참조, 할당이 가능하다.
  • 선언된 let, const는 상단에서 참조, 할당이 불가능하다.

 

🙋 왜 var는 되고 let, const는 안되나?

변수가 할당되기까지는 선언/초기화/할당의 3가지 단계를 거침

var는 호이스팅이 발생하면 선언과 초기화가 거의 동시에 이루어져서 실행 시점에 스코프 최상단에서 해당 변수에 대한 메모리가 살아있기 때문에 참조, 할당이 가능

let, const는 호이스팅이 발생 시 선언만 이루어지기 때문에 선언부를 만나기 전 까지는 초기화가 이루어지지 않은 상태. 따라서 해당 변수에 대한 메모리가 존재하지 않기 때문에 선언하기전에는 참조, 할당이 불가능

 

 

** let, const 선언문 전에 호출하는 경우 ⇒ 참조에러 발생

실제로 let 또는 const로 선언한 함수표현식을 상단에서 사용하려고 하면 초기화 하기 전에 접근할 수 없다는 ReferenceError가 나온다.

→ 위 현상을 TDZ(Temporal Dead Zone), 일시적 사각지대라고 한다. 변수는 존재하지만 초기화되어 있지 않은 상태이다.

 

 

** var에 함수를 할당하고 나중에 호출하는 경우 ⇒ 타입에러 발생

var 변수 sayHi는 참조는 가능하지만, 초기화만 이루어지고 함수가 할당이 되지 않은 상태이기 때문에 TypeError가 발생

 

참조에러(Reference Error): 엔진이 스코프에서 대상을 찾을 수 없을 때 발생. ex) 선언되지 않은 변수를 사용하려고 할 때, 없는 변수를 사용하려고 할 때
타입에러(Type Error): 엔진이 스코프 검색은 성공했으나, 대상을 가지고 불가능한 시도를 하였을 경우. ex) 함수가 아닌데 함수처럼 사용하려고 했을 때, iterable이 아닌데 iterator로 순회하려고 했을 때

 

 

참고 문서:

Arrow function | PoiemaWeb

[JS] ReferenceError / TypeError

함수 표현식 vs 함수 선언식

호이스팅에 대한 오해와 진실

JavaScript, 인터프리터 언어일까?