호이스트(hoist)
: 로프 또는 체인이 감싸는 드럼 또는 리프트 휠을 사용하여 하중을 들어 올리는 데 사용되는 장치, 또는 들어 올리는 행위 그 자체.
호이스트라는 단어의 의미를 생각해보면 javascript에서 호이스팅의 의미를 잘 기억할 수 있다.
코드에 선언된 변수 및 함수를 코드의 상단으로 끌어올려서 해당 변수 및 함수 유효 범위의 최상단에 선언하는 것을 말한다. 실제 코드가 끌어올려지는 것은 아니며, 자바스크립트 parser 내부적으로 끌어올려서 처리한다. 실제 메모리에는 변화가 없다.
호이스팅은 var 변수의 선언
과 함수선언문
에서만 일어난다.
먼저 변수 호이스팅은 변수 선언 및 초기화 시 변수가 속해있는 함수 안에서 최상단으로 올라가는 것이다. let/const 변수 선언 시 호이스팅이 발생하지 않는다.
console.log("Hi");
var name = "moone";
let name2 = "moone2";
↓ ↓ ↓ (javascript parser 내부에서 처리되는 결과)
var name; //var 변수 선언 (hoisting)
console.log("Hi");
name = "moone"; //변수에 할당
let name2 = "moone2"; //hoisting 발생하지 않음
함수 호이스팅은 함수의 선언이 코드의 최상단으로 끌어올려진다. 함수 표현식을 사용했을 때는 호이스팅이 발생하지 않는다.
first();
second();
function first() {
console.log("First hello");
}
var second = function() {
console.log("Second hello");
}
↓ ↓ ↓ (javascript parser 내부에서 처리되는 결과)
var second; //변수 선언 (hoisting)
function first() { //함수 선언문 실행 (hoisting)
console.log("First hello");
}
first();
second(); //Error 발생!!!
second = function() {
console.log("Second hello");
}
변수에 할당된 함수표현식은 hoisting을 통해 끌어 올려지지 않으므로, 이 때는 변수의 스코프 규칙을 따른다.
1) 함수 표현식의 선언이 호출보다 위에 있는 경우 (정상)
function sayHello(name) { // 함수선언문
var getName = function() { // 함수표현식
return "moone";
}
var userName = getName(); // 함수 "호출"
console.log("Hello, " + userName);
}
sayHello(); //"Hello, moone"
↓ ↓ ↓ (javascript parser 내부에서 처리되는 결과)
function sayHello(name) {
var getName; //함수표현식의 변수값 선언 (hoisting)
var userName; //var 변수값 선언 (hoisting)
getName = function() { // 함수표현식 할당
return "moone";
}
userName = getName(); // 함수 "호출"
console.log("Hello, " + userName);
}
sayHello(); //"Hello, moone"
2) 함수표현식의 선언이 호출보다 아래에 있는 경우 (TypeError)
function sayHello(name) { //함수 선언문
console.log(getName); //undefined => 선언은 되어 있지만 값이 할당되어 있지 않음
var userName = getName(); //error
console.log("Hello, " + userName);
var getName = function() { // 함수표현식 할당
return "moone";
}
}
sayHello(); //TypeError: getName is not a function
3) 함수표현식의 선언이 호출보다 아래에 있으며, let/const 변수에 할당 된 경우 (ReferenceError)
-> let/const의 경우 호이스팅이 일어나지 않음
function sayHello(name) {
console.log(getName); //error
let userName = getName();
console.log("Hello, " + userName);
let getName = function() {
return "moone";
}
}
sayHello(); //ReferenceError: getName is not defined
References
https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html
https://ojava.tistory.com/144
https://web-front-end.tistory.com/23