본문 바로가기

Javascript

자바스크립트 - hoisting

728x90
호이스팅이란?
코드에서 몇몇 타입의 변수들이 선언되기 전에 미리 접근하거나 사용할 수 있도록 만드는 것.
"변수들이 스코프의 최상단으로 이동한다" 라고 표현하기도 한다.

정의를 보면 변수들이 상단으로 이동한다고 말합니다.

 

하지만 실제로, 내부적으로 어떤 일이 일이 일어나는지 살펴봐야 합니다.

코드가 실행되기 전에, 어떤 변수가 선언되었는지 스캔하고, 각 변수마다 variable environment(변수 환경) 객체에 새로운 속성이 생성된다.

이것이 실제로 호이스팅이 작동하는 방식입니다.

정의에서 각 변수마다 새로운 속성이 생성된다고 했는데, 이것은 함수, var , let , const , arrow 함수 등에 따라

호이스팅 작동 방식이 달라지기 때문입니다.

 

호이스팅 작동 방식
  호이스팅 되었는가? 초기값 스코프
function declarations
(함수 표현식)
YES 실제 함수 Block
var variables
(var 변수)
YES undefined Function
let and const variables
(let 또는 const 변수)
NO(기술적으로는 YES) <uninitialized>, TDZ Block
function expressions 또는
arrow functions
var 또는 let/const 로 선언되는 것에 따라 달라짐

표를 통해 먼저 정리해보았습니다.

1. 함수 표현식의 경우 호이스팅이 일어납니다.

따라서 함수가 선언되기 전에 미리 사용할 수 있습니다. ( 변수 환경 객체에 저장됨 )

또한 함수마다 block 스코프를 가지는데, strict mode에서만 적용된다는 사실을 알아두어야 합니다.

 

2. var 변수의 경우도 호이스팅이 일어납니다.

하지만 함수와 달리 선언되기 전에 사용해보면 undefined 값을 가지게 됩니다.

이런 이유 때문에 var 변수 선언은 거의 사용되지 않습니다.

 

3. let과 const 변수의 경우는 호이스팅되지 않는다고 합니다.

그러나 사실 기술적으로 보면 호이스팅이 되는건 맞지만, 실제 값을 사용하려고 하면 uninitialized(초기화되지 않음)

이라고 나올 것입니다. 이런 특성 때문에 TDZ(Temporal Dead Zone)에 배치되었다고 말하기도 합니다.

 

4. 함수표현식 / 화살표 함수 의 경우 앞서 말한 var 또는 let/const 로 선언되는 것에 따라 달라집니다.

 

 

TDZ란 무엇일까?

if(myName == 'overaction') {
    console.log(`overaction ${food}`); // Uncaught ReferenceError: Cannot access 'food' before initialization
    const age = 2021 - 1998;
    console.log(age);
    
    const food = 'apple';
    console.log(x); // Uncaught ReferenceError: x is not defined
}

위 코드에서 food 변수는 const로 선언되었습니다.

따라서 선언하기 전 부분은 food 변수에 대한 TDZ 라고 할 수 있습니다. (블록 안의 첫줄 ~ 셋째줄)

 

그런데 아예 선언되지 않은 x 변수를 출력하려고 했을 때 나오는 오류는 또 달랐습니다.

 

이렇게 다르게 나오는 이유는, food 변수는 이미 자바스크립트 엔진이 코드를 읽었기 때문입니다.

따라서 변수 환경에 food 라는 변수를 이미 저장했고, 해당 변수를 선언한 곳에 도달하면 TDZ에서 제거되는 것입니다.

 

반면 x 변수는 아예 선언한 적이 없기 때문에 정의되지 않았다고 나옵니다.

 

 

다음 포스팅에서 예제를 더 살펴보겠습니다

 

728x90