우당탕탕

[JS] 호이스팅이란? ( Hoisting ) 본문

언어/JavaScript

[JS] 호이스팅이란? ( Hoisting )

모찌모찝 2022. 8. 22. 15:23
호이스팅이란?

 

호이스팅(Hoisting)

JavaScript로 개발을 진행하다 보면 호이스팅이라는 말을 들어본 경험이 있을 것이다.
보통은 호이스팅이라 하면 코드가 실행되기 전에 함수, 변수의 선언을 맨 위로 끌어올린다고 설명한다.
하지만 실제로 끌어올리는 것은 아니다. 

호이스팅이란 간단하게 말하면 아래와 같이 말할 수 있다.

호이스팅이란 코드가 실행되기 전에 변수 및 함수에 대한 메모리를 설정하는 것이다.


역시 말로만 보면 이해하기 어려울 수도 있으니 밑에 예시 코드를 통해 확인해보자

function hoist(a) {
    return a+1
}

var hoistV = "var hoist"

const hoistC = "const Hoist"

let hoistL = "let Hoist"

처음 코드가 실행되기 전에 JS 엔진이 해당 데이터 들에 대해 아래의 표처럼 메모리를 설정한다 

NAME VALUE
hoist < Function >
hoistV undefined
hoistC 초기화되지 않은 변수
hoistL 초기화되지 않은 변수

표를 보면 이해가 가는 사람도 있을 것이다. 
간단하게 설명하자면 이렇다.

var 타입의 경우 코드가 실행되기 전 메모리에 undefined로 자동으로 초기화된다.
const와 let 타입의 경우 코드가 실행되기 전 메모리에 초기화되지 않은 상태로 저장된다.
함수의 경우 함수 전체에 대한 참조가 함께 저장된다.

 

이제 해당 코드들을 위에서 한번 실행해보도록 하자

// 함수호출
console.log(hoist(2))
// var 호출
console.log(hoistV)
// const 호출
console.log(hoistC)
// let 호출
console.log(hoistL)


function hoist(a) {
    return a+1
}

var hoistV = "var hoist"

const hoistC = "const Hoist"

let hoistL = "let Hoist"

첫 번째 함수 호출에서는 메모리에 저장된 함수를 불러와 사용하여 3이 출력된다.
두 번째 var 호출에서는 선언 전 접근하여 메모리에 초기에 저장된 undefined가 출력된다.
세 번째 const와 네 번째 let의 경우에는 변수가 초기화되지 않아 Reference Error가 발생한다.

이후 코드가 모두 실행이 완료되면 메모리에는 우리가 선언한 var hoist / const hoist / let hoist와 같은 글이 출력되는 걸 볼 수 있을 것이다.

이와 관련하여 TDZ(시간상 사각지대)와 같은 말이 존재한다.
변수 스코프의 맨 위에서 변수의 초기화 완료 시점까지의 변수를 시간상 사각지대라  칭한다.

"시간상" 사각지대인 이유는, 사각지대가 코드의 작성 순서(위치)가 아니라 코드의 실행 순서(시간)에 의해 형성되기 때문입니다. 예컨대 아래 코드의 경우 let 변수 선언 코드가 그 변수에 접근하는 함수보다 아래에 위치하지만, 함수의 호출 시점이 사각지대 밖이므로 정상 동작합니다. - MDN web docs

아래는 예시 코드이다.

{
    // TDZ가 스코프 맨 위에서부터 시작
    const func = () => console.log(letVar); // OK

    // TDZ 안에서 letVar에 접근하면 ReferenceError

    let letVar = 3; // letVar의 TDZ 종료
    func(); // TDZ 밖에서 호출함
}

 

최근 현업에서는 let과 const를 주로 사용하여 의도치 않은 실수를 코드 실행 시 ReferenceError를 통해 바로 발견할 수 있었지만, 이전에 내가 투입되었던 프로젝트나 은행권 프로젝트에서는 아직도 var로만 사용하는 곳이 좀 있다. 만약 var 타입으로 사용하는 코드에서는 예기치 않게 undefined가 들어가 의도하지 않은 동작으로 이어질 수 있으니 조심하도록 하자

Reference

https://dev.to/lydiahallie/javascript-visualized-hoisting-478h
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let#%EC%8B%9C%EA%B0%84%EC%83%81_%EC%82%AC%EA%B0%81%EC%A7%80%EB%8C%80

Comments