사전에서 찾아보면 hoisting이란 말은 "끌어올리기" 입니다. 그렇다면 javascript에서 hoisting은 어떤걸 말하는 걸까요?

변수 Hoisting

변수를 선언과 할당으로 나눌 수 있습니다.

var foo = 'bar'; //

예제를 보면 선언과 할당을 동시에 한 것과 같이 보입니다.
javascript 엔진에서는 선언을 먼저 끌어올립니다.

var foo = 'bar';
// 실제 엔진에서는...
var foo; // (1) 선언
console.log(foo); // undefined - foo에 값이 "할당" 이 되지 않았기 때문입니다.
foo = 'bar'; // (2) 할당
console.log(foo); // 'bar'

값을 선언하지 않고 값을 실행하면 에러가 발생합니다.

console.log(bar); // Uncaught ReferenceError: bar is not defined
var bar;
bar = 'bowbow';
console.log(bar) // bowbow

전역에서 변수선언과 함수 안에서 변수선언은 독립적입니다. 함수 안에서 변수선언을 하면 함수안에서 최상위로 hosting 됩니다.

var global = 'GLOBAL';
var local = 'LOCAL';
function localFunc() {
    var local = 'local';
    return local;
}
console.log(localFunc()); // local
console.log(global); // GLOBAL
console.log(local); // LOCAL

변수 선언은 독립적이라서 상관은 없지만 변수선언 키워드를 사용하지 않고 global에 변수선언하고 함수내에서 같은 변수명을 사용하면 global 값이 달라집니다. 이점을 유의해야합니다.

var global = 'GLOBAL';
console.log(global):
function localFunc() {
    global = 'function variable';
    return global;
}
console.log(localFunc()); // 'function variable'
console.log(global); // 'function variable''

함수 Hoisting

함수는 두가지로 작성 할 수 있습니다. 함수선언식과 함수표현식입니다.
함수선언식은 function 키워드로 시작합니다. 변수선언과 달리 값을 먼저 실행하고 함수선언을 나중에 해줘도 함수가 실행됩니다.

console.log(hello());
function hello() {
    return 'world';
}

함수표현식은 변수에 함수를 할당합니다. 함수표현식은 변수선언의 Hoisting과 같은 Hoisting이 적용됩니다. 그래서 함수표현식을 이용해서 hoisting 되지않고 함수부터 실행하면 TypeError가 발생합니다.

console.log(hello()); // Uncaught TypeError: hello is not a function
var hello = function() { return 'world' };