호이스팅(Hoisting)은 자바스크립트에서 코드 실행이 시작되기 전에 변수와 함수 선언을 해당 스코프의 최상단으로 끌어올리는 동작 방식입니다. 스코프 내 어디에 함수나 변수가 선언되어 있든, 실행 시점에는 마치 스코프 맨 위에 선언된 것처럼 처리됩니다.
다만 주의할 점은, 호이스팅은 오직 선언(declaration)만 끌어올린다는 것입니다. 값의 할당(assignment)은 원래 위치 그대로 남아 있습니다.
함수 호이스팅 예제
console.log(functionBelow("Hello"));
function functionBelow(greet) {
return `${greet} world`;
}
console.log(functionBelow("Hi"));
실행 결과
Hello world Hi world
위 예제를 보면 함수가 호출된 이후에 선언되었음에도 정상적으로 실행되었습니다. 이것이 바로 함수 호이스팅 덕분입니다. 자바스크립트 엔진이 코드를 실행하기 전에 함수 선언 전체를 스코프 상단으로 올려두기 때문에, 선언 위치보다 앞에서 호출해도 아무 문제 없이 동작합니다.
변수 할당 방식으로 함수를 선언하면?
그러나 함수를 변수처럼 할당하는 방식으로 선언하면 호이스팅이 적용되지 않습니다.
console.log(functionBelow("Hello"));
var functionBelow = function(greet) {
return `${greet} world`;
}
console.log(functionBelow("Hi"));
이 코드는 다음과 같은 에러와 함께 실패합니다.
TypeError: functionBelow is not a function
만약 var 키워드를 제거하면 에러 메시지가 달라집니다.
ReferenceError: functionBelow is not defined
왜 이런 차이가 발생할까?
var로 선언된 경우, 변수 자체는 호이스팅되어 컨텍스트에 등록되지만 값은 할당되지 않은 채 undefined로 초기화됩니다. 이를 변수 호이스팅(variable hoisting)이라고 합니다.
즉, 함수가 호출되는 시점에는 functionBelow라는 이름은 존재하지만 아직 함수가 아니라 undefined인 상태이므로 "is not a function" 에러가 발생하는 것입니다. 반면 var 없이 선언하면 변수 자체가 등록되지 않아 "is not defined" 에러가 발생합니다.
이러한 특성 때문에 익명 함수(anonymous function)와 화살표 함수(arrow function)는 자바스크립트에서 절대 호이스팅되지 않습니다. 안전하고 예측 가능한 코드를 작성하려면 함수를 사용하기 전에 반드시 먼저 선언·정의하는 습관을 들이는 것이 좋습니다.