2015년 2월 26일 목요일

[JavaScript] Hoisting(호이스팅) 이란?

부제 : 함수 선언과 함수 표현의 차이
Function Declaration vs Function Expression


함수 선언과 함수 표현의 가장 큰 차이는 바로 Hoisting이다.
이걸 제대로 이해하기 위해서는 Execution Context에 대한 이해가 필수이니 이 글(클릭하기)를 읽고 와주길 바란다.

우선 Hoisting에 대해 간단히 말하자면, 후선언된 변수나, 함수들이 해당 Scope에서 최상위에 위치하는걸 뜻한다.
자바스크립트엔진은 해당 Execution Context의 생성시, 즉 Runtime 시점에서 변수선언문이나 함수선언문을 읽기 전에 선언된 변수와 함수들을 다른 무엇보다도 먼져 읽어 Scope의 최상위에 위치시킨다. 이 덕에, 훨씬 뒤에서 선언된 함수들과 변수들을 그 전에 사용이 가능하다.

*참고로 변수의 경우에는 변수 선언(Variable Declaration)만 Hoisting 된다, 즉 Variable Initialization이 있다면 변수가 선언은 되나, 변수에 어떤 값도 들어가지 않는다는 뜻.

*또한 함수의 Execution Context의 생성은 함수 호출시 이뤄지므로, 함수 내부에서 선언된 변수들은 함수 호출시에서야 Hoisting 된다.


console.log(internalFunction);// 함수가 Hoisting 됐을뿐, 아직 Execution Context는 생성되지 않았으므로, 에러가 발생한다.

functionDeclaration();// 함수가 성공적으로 호출되며 Function Declaration가 프린트 된다.

console.log();// Undefined 가 프린트 된다. 변수에 "vart"라는 값이 어싸인되는것은 아래 코드가 읽히는 시점에서기 때문.

function functionDeclaration() {
    console.log("Function Declaration");
    
    function internalFunction(){
    }
}

var t = "vart";

functionExpression(); // 에러가 발생

console.log(novalue); // Context에서 선언된적 없는 변수인 novalue를 호출할 수가 없어 에러가 발생

var functionExpression = function() {
    console.log("Function Expression");
}


그럼 이제 Hoisting을 제대로 이해했는지 확인도 할겸 아래 코드의 결과를 알아 맞춰보자.


function test1() {
    function internalFunction() {
 return true;
    }

    return internalFunction();

    function internalFunction() {
 return false;
    }
}

console.log(test1());

function test2() {
    var internalFunction = function() {
 return true;
    }

    return internalFunction();

    var internalFunction = function() {
 return false;
    }
}

console.log(test2());

function test3() {
    return internalFunction();

    var internalFunction = function() {
 return true;
    }

    var internalFunction = function() {
 return false;
    }
}

console.log(test3());

function test4() {
    var internalFunction = function() {
 return true;
    }

    return internalFunction();

    function internalFunction() {
 return false;
    }
}

console.log(test4());






정답은


  • test1 = false
  • test2 = true
  • test3 = TypeError: undefined is not a function
  • test4 = true
    • 참고로 test4는 hoisting 되었던 함수가 변수 표현문으로 다시 정의되어 true값을 반환하게 된다.
    • 기억하자, 자바스크립트에서는 함수 또한 객체에 불과하다. 그러니 재정의될 수 있다.

댓글 없음 :

댓글 쓰기