호이스팅이 일어나면, 변수와 함수의 메모리 공간을 미리 확보하고 확보한 공간의 주소값이 변수 혹은 함수에 연결된다. 자바스크립트 엔진이 컴파일 시점에 코드를 미리 읽어 선언된 식별자를 수집하는 과정을 통해 실행 컨텍스트가 활성화 되기 전일지라도 해당 환경에 선언되어 있는 식별자 정보를 미리 알고 있는 것이다. 따라서 동일한 실행 컨텍스트(or 스코프) 내에서는 선언 및 실행의 순서에 무관하게 변수나 함수에 접근이 가능하게 된다.
즉, 실제로 변수와 함수의 선언부의 위치가 스코프의 최상단으로 변경되는 것이 아니라 끌어올린 것으로 간주되는 것으로 호이스팅이 가능하려면 몇가지 조건이 존재한다.
이는 호이스팅이 일어날 때 '선언부'만 끌어올리고 할당(or 초기화) 과정은 그 자리에 그대로 남겨두기 때문인데, let/const의 경우 실질적인 할당이 일어나기 전까지는 "시간상 사각지대(TDZ)" 에 놓여 실행시점 이전까지 초기화가 일어나지 않기에 초기화 이전에 참조를 하면 참조에러(ReferenceError)를 만난다.
hoisting()
function hoisting(){
var varText = 'Hoisting'; // 수집1: 선언 + 초기화 + 할당
console.log(varText) // (1) expected : 'Hoisting'
var varText; // 수집2: 선언
console.log(varText) // (2) expected : undefined
console.log(letText) // (3) expected : undefined
let letText = 'None' // 수집3: 선언 + 초기화 + 할당
// ***** 변수의 호이스팅 대상은 변수의 선언부이기 때문에,
// 호이스팅이 일어난 이후 코드 순서와 변수 선언부는 아래와 같이 변경되는 것처럼 작동한다.
}
-------------------------------------------------------------------------------------
hoisting()
function hoisting(){
var varText; (1) // 수집1: 선언 + 초기화
var varText; (2) // 수집2: 선언 + 초기화
let letText; (3) // 수집3: 선언, 초기화 x
varText = 'Hoisting'; // 수집1의 데이터 힐당
console.log(varText) // (1) output : 'Hoisting'
console.log(varText) // (2) output : 'Hoisting'
console.log(letText) // (3) output : undefined
letText = 'None' // 수집3의 데이터 할당 -> 실질적 선언부. 이때 초기화 됨
}
참조
mdn-hoisting
호이스팅이란?
호이스팅의 오해와 진실
도서 - 코어 자바스크립트