Muscardinus
Hoisting 본문
Hoisting?
Hoisting이란, 변수 및 함수를 Compile 단계에서 memory에 넣는 과정이다. JS에서는, function은 완전히 hoisting되고, 변수는 var로 선언된 변수는 hoisting 되고, undefined로 초기화된다. 완전한 hoisting이 아니다. let 과 const 변수는 hoisting이 되지만, undefined로 초기화 조차 안된다. var 보다 더 불완전한 hoisting이다.
var로 선언된 변수는 따라서, code상으로 값이 할당되는 구간 전 까지는 undefined의 값을 가지게 된다. 반면, function의 경우, 완전히 hoisting이 되었기에, 어디에서나 호출된다. let과 const가 사용된 변수는, 선언 전에 호출 할 경우 reference error을 던진다.
// function expression gets hoisted as undefined
var sing = function () {};
이 코드는 실제로는
var sing = undefined;
sing = function () {};
이와 같은 방법으로 작동하고 있는 것이다.
// variable declaration gets hoisted as undefined
var favoriteFood = "grapes";
// function expression gets hoisted as undefined
var foodThoughts = function () {
// new execution context created favoriteFood = undefined
console.log(`Original favorite food: ${favoriteFood}`);
// variable declaration gets hoisted as undefined
var favoriteFood = "sushi";
console.log(`New favorite food: ${favoriteFood}`);
};
foodThoughts();
위 코드를 보면 알 수 있듯이, favoriteFood라는 변수가 두 번 선언되었지만, 저번 Execution Context 글에서도 볼 수 있듯이, Functional Execution Context가 foodThoughts에서도 작용하여 foodThoughts 내부에서는 favoriteFood가 sushi가 된다.
for (var i = 0; i < 2; i++) {
console.log(a); // undefined
if (i > 0) {
var a = 2;
}
}
위 코드를 보면 알 수 있지만, a는 undefined가 된다. 기억하자, execution context는 {}가 있는 기준이 아니라, function과 global에서만 작용한다. 그러므로 비록 조건문이 있더라도, var는 global로 hoisting된다.
신기한 Hoisting 세계
var foodThoughts = function () {
favoriteFood = 2;
console.log(`Original favorite food: ${favoriteFood}`);
console.log(`New favorite food: ${favoriteFood}`);
};
foodThoughts();
favoriteFood;
위 코드는 신기하게도 작동한다. 찾아보니, 신기하게도 foodThoughts 함수 내에서 Execution Context가 작용하여 favoriteFood가 할당된 var을 찾다가, 없어서 global로 이동하여 찾는데 없으므로, global에 var favoriteFood = undefined가 생성된다.
주의: 우리가 비록 Hoisting을 배웠지만, 이것은 심각한 memory leak 및 bug를 찾는데 상당한 어려움을 준다. 그러므로 변수 선언 시 let 와 const를 사용하자. 하지만, 알아두는 것은 나쁜것이 아니다!
'FrontEnd > JavaScript Basics' 카테고리의 다른 글
Prototype (0) | 2020.12.17 |
---|---|
Lexical Environment (0) | 2020.12.16 |
Execution Context (0) | 2020.12.15 |
Static Vs Dynamic Typed (1) | 2020.12.15 |
Type Coercion (0) | 2020.12.15 |