호이스팅이란 var 로 선언한 표현식나 function 선언문 등을 실행 단계에서 해당 Scope의 맨 위로 옮기는 것을 말합니다.
자바스크립트는 코드를 실행하기 전에 var 선언문과 function 선언문을 해당 스코프의 맨위로 옮겨버립니다.
함수 호이스팅이 발생하는 원인은 자바스크립트 변수 생성과 초기화(선언과 할당)가 분리되어 진행되기 때문입니다.
코드로 살펴보겠습니다.
/* sum이라는 함수를 실행해서 1+3값을 result 에 넣어주려고합니다. 하지만 실행해보시면 sum is not a function 이라는 에러가 발생합니다.. 왤까요??.. sum 이라는 함수는 분명 아래 존재하는데 말이죠..?? 어떻게 된일인지 살펴봅시다.*/var result =sum(1,3); varsum=function(num1, num2){returnconsole.log(num1+num2);}
위의 코드는 실행단계에서 아래와 같은 코드로 변형됩니다.
// var 로 선언되어있는 녀석들이 맨위로 끌어올려집니다. 이때는 변수만 선언될뿐 초기화는 진행되지않아요var result =undefined; var sum =undefined; result =sum(1,3); // 후에 이렇게 위에 선언된 변수들에 초기화가 이루어집니다.sum=function(num1, num2){ // 마찬가지입니다.returnconsole.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); // 놀랍게도 이 때는 실행이됩니다! functionsum(num1, num2){ // var sum 같은 표현식이아닌 함수 선언식으로 되어있기 때문에 함수가 그대로 끌어올려집니다.returnconsole.log(num1+num2);}
위에 코드가 동작하는 이유는 변수호이스팅과 함수호이스팅이 다르기 때문입니다.
변수 호이스팅의 경우 undefiend로 변수 생성이 되지만 함수는 그대로 맨 위로 올라오기 때문입니다.
주의할점
변수와 함수명이 같을 때 변수에 값이 초기화되어있다면 변수가 함수를 덮어 씌웁니다.
var getName ='olaf';functiongetName(){console.log('olaf');}console.log(typeof getName); // string
반대로 변수값이 undefiend 로 선언되어 있을 경우 변수를 함수가 덮습니다.
var getName; // undefinedfunctiongetName() {console.log("appear");}console.log(typeof getName); // function
결론
함수나 변수를 사용하기전에는 항상 미리 선언을 해두고 사용하시는 버릇을 들이는게 가독성에도 디버깅에도 좋습니다.