호이스팅(Hoisting)

앞서 var변수를 얘기하면서, 호이스팅에 대해서 거론하였습니다.

호이스팅이란 선언부를 유효범위의 최상위로 끌어올리는 것을 말합니다.

<br/>

호이스팅은 변수 호이스팅 / 함수 호이스팅으로 구분할 수 있습니다.

<br/>

먼저 변수 호이스팅은 다음 코드를 볼 수 있습니다.

function foo(){
  var a = 10;
  var a = 20;
  console.log(a); // 20
}

a변수를 두번 선언함에도 에러가 발생하지 않습니다.

이유는 호이스팅이 선언부를 function-scope의 최상위로 끌어올렸기 때문입니다.

<br/>

내부적으로는 다음과 같이 읽을것 입니다.

function foo(){
  var a;
  a = 10;
  a = 20;
  console.log(a); //20
}

<br/>

또 다음과 같은 코드도 동일하게 동작합니다.

function foo(){
  var a = 10;
  if(true){
  	var a = 20;
  }
  console.log(a);
}
foo();

<br/>

호이스팅되어서 다음과 같이 내부적으로 동작합니다.

function foo(){
  var a;
  a = 10;
  if(true){
  	a = 20;
  }
  console.log(a); // 20
}
foo();

<br/>

let, const는 호이스팅을 하지 않습니다.

따라서 동일한 변수를 두번선언한 경우 에러를 출력할 것입니다.

<br/>

<br/>

다음은 함수 호이스팅입니다.

함수 호이스팅은 함수선언을 최상위로 끌어올리는것을 말합니다.<br />
! 함수선언식만이 호이스팅을 합니다.

<br/>

함수 선언식과 함수표현식은 다음과 같이 구분합니다.

/** 함수 선언식 **/
//Function Declarations
function foo() {
    console.log('hello');
}
/** 함수 표현식 **/
//anonymous function expression
var foo = function() {
    console.log('hello');
};

//named function expression
var foo = function foo() {
    console.log('hello');
};

// 자기호출함수, self invoking function expression
(function foo() {
    console.log('hello');
})();

<br/>

다음 코드를 보면 함수호이스팅을 볼 수 있습니다.

foo();
function foo(){console.log("hello")} //hello

foo 함수가 후에 선언되었음에도, 에러를 출력하지 않고 정상 수행됩니다.

자바스크립트 엔진이 구동 시 최우선으로 함수선언식을 수집하여 최상위 Scope로 끌어올리기 때문입니다.

<br/>

그럼 다음 코드를 볼까요.

function foo(){
    function bar() {
        console.log('hello');
    }

    return bar();

    function bar() {
        console.log('world');
    }
}
foo();

// world

결과는 world를 출력합니다.

호이스팅에 의해 함수선언식이 최우선적으로 수집되어 최상위 Scope로 끌어올려졌기 때문입니다.

<br/>

function foo(){
    var bar= function() {
        console.log('hello');
    };
    return bar();
    var bar = function() {
         console.log('world');
    };
}
foo();

// hello

하지만 다음코드는 hello를 출력합니다.

bar 함수가 함수표현식으로 선언되었기 때문입니다.

따라서 호이스팅 하지 않았고, 후에 선언된 bar 함수를 읽지 않았기 때문입니다.

<br />

참고

<a href="http://insanehong.kr/post/javascript-function/">Function Declarations(함수선언) vs Function Expressions(함수표현)</a>

0
이전 댓글 보기
등록
TOP