함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말한다.
자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언한다.
자바스크립트 Parser
가 함수 실행 전 해당 함수를 한 번 훑는다.
함수 안에 존재하는 변수/함수선언에 대한 정보를 기억하고 있다가 실행시킨다.
유효 범위: 함수 블록 {} 안에서 유효
즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 값들을 끌어올리는 것이다.
실제로 코드가 끌어올려지는 건 아니며, 자바스크립트 Parser
내부적으로 끌어올려서 처리하는 것이다.
실제 메모리에서는 변화가 없다.
foo();
foo2();
function foo() { // 함수선언문
console.log("hello");
}
let foo2 = function() { // 함수표현식
console.log("hello2");
}
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 - 위와 동일 --- */
let foo2; // [Hoisting] 함수표현식의 변수값 "선언"
function foo() { // [Hoisting] 함수선언문
console.log("hello");
}
foo();
foo2(); // ERROR!!
foo2 = function() {
console.log("hello2");
}
함수표현식은 함수선언문과 달리 선언과 호출 순서에 따라서 정상적으로 함수가 실행되지 않을 수 있다.
함수표현식에서는 선언과 할당의 분리가 발생한다.
/* 정상 */
function printName(firstname) { // 함수선언문
let inner = function() { // 함수표현식
return "inner value";
}
let result = inner(); // 함수 "호출"
console.log("name is " + result);
}
printName(); // > "name is inner value"
/* 오류 */
function printName(firstname) { // 함수선언문
console.log(inner); // > "undefined": 선언은 되어 있지만 값이 할당되어있지 않은 경우
let result = inner(); // ERROR!!
console.log("name is " + result);
let inner = function() { // 함수표현식
return "inner value";
}
}
printName(); // > TypeError: inner is not a function
/** --- JS Parser 내부의 호이스팅(Hoisting)의 결과 --- */
/* 오류 */
function printName(firstname) {
let inner; // [Hoisting] 함수표현식의 변수값 "선언"
console.log(inner); // > "undefined"
let result = inner(); // ERROR!!
console.log("name is " + result);
inner = function() {
return "inner value";
}
}
printName(); // > TypeError: inner is not a function
같은 이름의 var 변수 선언과 함수 선언에서의 호이스팅
변수 선언이 함수 선언보다 위로 끌어올려진다.
참고 | https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html