javascript 호이스팅

zne·2021년 6월 28일
1

자바스크립트 var, let, const 선언 키워드들의 차이점을 찾아보다가 호이스팅과 관련해서 헷갈리는 부분이 있었다. var로 선언했을 때만 호이스팅이 발생하는줄 알았는데 자바스크립트 선언 키워드들은 모두 호이스팅이 발생한다고 한다. 호이스팅이 일어날 때 var와 let, const 키워드의 차이점에 대해서 알아보자.

호이스팅이란?

호이스팅은 선언문이 해당 스코프의 제일 위로 끌어올려져 동작하는 것을 말한다.

a(); // "a"
function a() {
  console.log("a")
}

함수가 선언되기 전 함수를 실행하고 있지만 에러가 나지 않고 함수가 실행되는 것을 볼 수 있다. 이는 호이스팅이 일어나 코드가 실행될 때 함수가 제일 상단으로 끌어올려져 동작하기 때문이다.

함수 선언식과 함수 표현식에서 호이스팅

a(); // "a"
b(); // Uncaught TypeError: b is not a function
function a() {
  console.log("a")
}
var b = function () {
  console.log("b")
}

위의 코드를 실행시키면 함수 a는 잘 실행되는 반면, 함수 b는 타입에러가 난다.
두 함수 모두 실행시키는 시점에서 함수가 선언되지 않았지만, _함수 선언식으로 된 a는 호이스팅의 영향을 받고 함수 표현식으로 된 b는 호이스팅의 영향을 받지 않는다는 것을 알 수 있다.

var 호이스팅

변수는 다음 3단계를 거쳐 생성된다.

선언 단계 - 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계
초기화 단계 - 변수의 메모리 공간을 확보하고 변수를 undefined로 초기화하는 단계
할당 단계 - 초기화 된 변수에 실제 값을 할당하는 단계

console.log(h) // undefined
var h = "hoisting" 

위의 코드가 실행되는 순서는 다음과 같다.

  1. h가 변수 객체에 등록되고(선언 단계) 동시에 메모리 공간이 확보되면서 undefined로 초기화 된다(초기화 단계).
  2. 변수 할당문에 도달하면 undefined에서 "hoisting"으로 실제 값이 할당된다.

즉, var는 선언 단계와 초기화 단계가 동시에 진행되면서 바로 메모리 공간이 생기고 초기값인 undefined가 할당되기 때문에 변수 선언문 이전에 변수에 접근해도 에러가 발생하지 않는다.

let, const 호이스팅

console.log(h) // Uncaught ReferenceError: h is not defined
let h = "hoisting"

위 코드가 실행되는 순서는 다음과 같다.

  1. h가 변수 객체에 등록된다. (선언 단계)
    ---------(일시적 사각지대)---------
  2. 메모리에 변수 공간을 확보 한 후, undefined로 초기화한다.(초기화 단계)
  3. 실제값 "hoisting"을 할당한다.

위의 코드를 보면 참조에러가 나면서 호이스팅이 일어나지 않는것 처럼 보인다.
let, const로 선언된 키워드는 선언 단계와 초기화 단계가 분리되어 진행되는데, 변수 선언문 이전에 변수에 접근할 때 초기값이 할당되어 있지 않아 참조 에러(ReferenceError)가 발생하는 것이다.

이는 호이스팅이 일어나지 않는 것이 아니라, 변수를 위한 메모리 공간이 확보되지 않아 초기화 시작 시점까지 참조를 할 수 없게 되는 구간이 발생하는 것인데 이를 일시적 사각지대(Temporal Dead Zone; TDZ)라고 한다.


Reference

https://poiemaweb.com/es6-block-scope
https://medium.com/@yeon22/javascript-var-let-const%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90-9fab5c264c9c
https://joshua1988.github.io/web-development/javascript/function-expressions-vs-declarations/

0개의 댓글