09. 호이스팅 (Hoisting)

함수 호이스팅과 변수 호이스팅에 대해서 학습합니다.

호이스팅이란 무엇 일까요?

호이스팅이란 var 로 선언한 표현식나 function 선언문 등을 실행 단계에서 해당 Scope의 맨 위로 옮기는 것을 말합니다.

자바스크립트는 코드를 실행하기 전에 var 선언문과 function 선언문을 해당 스코프의 맨위로 옮겨버립니다. 함수 호이스팅이 발생하는 원인은 자바스크립트 변수 생성과 초기화(선언과 할당)가 분리되어 진행되기 때문입니다.

코드로 살펴보겠습니다.

/* 
   sum이라는 함수를 실행해서 1+3값을 result 에 넣어주려고합니다.
   하지만 실행해보시면 sum is not a function 이라는 에러가 발생합니다..
   왤까요??.. sum 이라는 함수는 분명 아래 존재하는데 말이죠..??
   어떻게 된일인지 살펴봅시다.
*/  
var result = sum(1,3); 
var sum = function(num1, num2){
   return console.log(num1+num2);
}

위의 코드는 실행단계에서 아래와 같은 코드로 변형됩니다.

// var 로 선언되어있는 녀석들이 맨위로 끌어올려집니다. 이때는 변수만 선언될뿐 초기화는 진행되지않아요
var result = undefined; 
var sum = undefined; 
result = sum(1,3);  // 후에 이렇게 위에 선언된 변수들에 초기화가 이루어집니다.
sum = function(num1, num2){ // 마찬가지입니다.
   return console.log(num1+num2);
}

몇 가지 다른 코드를 더 살펴보겠습니다.

// 어떤게 찍힐거같으신가요 ? 당연히 olaf 이겠죠
console.log(name);  // 하지만 예상과 다르게 값은 undefined 입니다...
var name = 'olaf';
var age = 27;
// 코드를 실행하면 undefined로 미리 변수가 생성되고
var name = undefined;
var age = undefined;
name = 'olaf'; // 후에 초기화가 이뤄지기 떄문이에요
age = 27

함수 선언식에서의 호이스팅은 다르게 동작합니다.

var result = sum(1,3); // 놀랍게도 이 때는 실행이됩니다! 
function sum(num1, num2){ // var sum 같은 표현식이아닌 함수 선언식으로 되어있기 때문에 함수가 그대로 끌어올려집니다.
   return console.log(num1+num2);
}

위에 코드가 동작하는 이유는 변수호이스팅함수호이스팅이 다르기 때문입니다. 변수 호이스팅의 경우 undefiend로 변수 생성이 되지만 함수는 그대로 맨 위로 올라오기 때문입니다.

주의할점

변수와 함수명이 같을 때 변수에 값이 초기화되어있다면 변수가 함수를 덮어 씌웁니다.

var getName = 'olaf';
function getName(){
  console.log('olaf');
}
console.log(typeof getName); // string

반대로 변수값이 undefiend 로 선언되어 있을 경우 변수를 함수가 덮습니다.

var getName; // undefined
function getName() {
     console.log("appear");
}
console.log(typeof getName); // function

결론

함수나 변수를 사용하기전에는 항상 미리 선언을 해두고 사용하시는 버릇을 들이는게 가독성에도 디버깅에도 좋습니다.

Last updated