[JavaScript] 호이스팅(Hoisting)

Dodam·2023년 9월 12일
0

[JavaScript]

목록 보기
7/10
post-thumbnail

자바스크립트에서의 변수 처리

자바스크립트에서는 총 3단계에 걸쳐 변수를 생성한다.

  1. 선언 단계(Declaration phase)

    • 변수 객체(variable Object)를 생성하고 변수를 등록한다.
    • 스코프는 해당 변수 객체를 참조한다.
  2. 초기화 단계(Initialization phase)

    • 변수 객체(Variable Object)에 등록된 변수를 메모리에 할당한다.
    • 변수는 undefined로 초기화된다.
  3. 할당 단계(Assignment phase)

    • undefined로 초기화된 변수에 실제값을 할당한다.


자바스크립트에서는 var, let, const 키워드를 붙여 변수를 생성한다.
이는 기본적으로 3단계를 거쳐서 실행되지만 실행되는 순서가 조금씩 다르다.

let, const

let의 경우 선언 단계와 초기화 단계가 분리되어 있고 그 사이에 TDZ(Temporal Dead Znone)가 존재한다.
이 TDZ에 접근할 경우 Reference Error가 발생하게 된다.
const의 경우 let과는 달리 선언 단계와 초기화 단계가 동시에 실행된다. 하지만 그전에 TDZ가 생성되어 TDZ에 접근할 경우 역시 Reference Error가 발생한다.

console.log(value)	// 선언 단계 → TDZ
let value = 'Hello World' // 초기화 단계 → 할당 단계

// ReferenceError: Cannot access 'name' before Initialization
console.log(value)	// TDZ
const value = 'Hello World' // 선언 단계 → 초기화 단계 → 할당 단계

// ReferenceError: Cannot access 'name' before initialization

var

var는 let, const와 달리 TDZ가 존재하지 않는다.
var는 선언 단계와 초기화 단계가 동시에 진행되며, 선언과 동시에 undefined로 초기화된다.

console.log(value)	// 선언 단계 → 초기화 단계
var value = 'Hello World' // 할당 단계

// undefined

var과 let, const의 차이는 TDZ의 유무이다.
여기서 TDZ(Temporal Dead Zone)은 스코프 혹은 라이프 사이클의 시작지점부터 초기화 단계 직전까지의 구간을 의미한다.

호이스팅(Hoisting)

호이스팅이란 스코프(함수) 안에 존재하는 모든 선언들을 해당 스코프(함수)의 최상단으로 끌어올리는 것을 말한다. 자바스크립트 엔진은 코드를 실행하기 전에 실행 가능한 코드를 형상화하고 구분하는 과정을 거친다.
이 과정에서 자바스크립트 엔진은 코드 실행을 위한 모든 선언들을 스코프에 등록(메모리에 저장)한다.

호이스팅의 대상은 두 가지가 있다.

  • variable declaration(변수 선언)
  • function delclaration(함수 선언)

여기서 중요한 점은 선언에만 호이스팅이 일어난다는 점이다.
선언에서만 호이스팅이 일어나기 때문에 값을 할당하더라도 할당된 값은 호이스팅이 일어나지 않는다.
이는 위의 let, const 예제에서 Reference Error가 발생하는 이유이기도 하다.

console.log(value)	// undefined
var value = 'Hello World'

// 해당 코드에서 var가 에러가 나지 않는 이유는 값이 할당되진 않지만 선언과 동시에 undefined로 값이 초기화 되어있기 때문

대부분 var는 호이스팅이 되고 let, const는 호이스팅이 되지 않는다고 생각하는데, let과 const도 호이스팅이 된다. 다만 아무런 값도 할당되어 있지 않기 때문에 에러가 나는 것이다.

함수 선언에서의 호이스팅

함수 선언의 경우 선언 단계, 초기화 단계, 할당 단계를 동시에 진행한다.
때문에 TDZ도 존재하지 않는다.

아래 함수 선언식으로 생성된 fun1 함수와 함수 표현식으로 생성된 fun2 함수가 있다.
fun1 함수의 경우 제대로 호출되지만, fun2 함수의 경우 함수가 할당되지 않은 것을 볼 수 있다.
호이스팅은 선언만 스코프(함수)의 위로 끌어올리기 때문에 함수를 할당할지라도 할당한 값은 호이스팅되지 않기 때문에 다음과 같이 에러가 나는 것이다.

fun1()
fun2()

function fun1() {
	console.log(value)
  	var value = 'Hello World'
}

var fun2 = function() {
	console.log(value)
  	var value = 'Hello World'
}

// undefined
// TypeError: fun2 is not a function
profile
⏰ Good things take time

0개의 댓글