console.log(a); // Reference Error
선언되지 않은 변수를 참조할 경우, 보통 이렇게 오류가 나타난다.
console.log(a); // undefined
var a = 1;
console.log(a); // 1
하지만 위의 예제에는 오류가 나타나지 않는다.
선언되지 않은 변수를 참조하는데 오류가 나지 않고 undefined로 값이 지정된 이유는 바로 Hoisting 때문이다. 위 코드의 실제 실행 과정은 대략 아래와 같이 실행된다고 볼 수 있다.
var a; // 변수 선언부분만 끌어올려졌다.
console.log(a); // undefined
a = 1;
console.log(a); // 1
Hoisting은 쉽게 생각하여 변수를 스코프 내 최상위로 끌어올린다고 생각하면 된다.
함수의 Hoisting도 변수의 Hoisting과 같은 맥락이지만 변수의 Hoisting이 변수 선언문 및 초기화였다면 함수는 함수 선언문 방식일때만 Hoisting이 된다. ( 함수 선언문을 제외한 방식들은 변수선언과 같이 함수 자체가 아직 선언이 되지 않은거라 오류가 발생한다. )
또한 let
과 const
변수 선언에서는 호이스팅이 발생하지 않는다.
함수표현식이란, 변수를 만들고 함수를 할당해주는 표현식이다.
d(); // ERROR, undefined는 호출할 수 없기 때문에
var d = function () {
console.log('I am inside function d');
};
d();
d
변수가 선언된 후 d
의 값인 함수를 아직 할당을 받지 못한 상태에서 d
함수를 호출했음으로 error가 발생했다.
함수 선언식으로 선언한 함수는 무조건 hoisting이 되며 함수 자체가 hoisting이 된다.
j();
function j () {
console.log('j');
};
j();
위 예제가 실제 실행이 될때는 아래와 같이 함수 자체가 끌어올려진다.
function j () {
console.log('j');
};
j();
j();
new Function또한 Hoisting의 영향을 받지 않는다.
showName(); // ERROR
var showName = new Function("", console.log("David Kwon"));
var
와 달리 let
과 const
로 변수를 선언할 경우, Hoisting의 영향을 받지 않는다.
console.log(a); // a를 찾지 못해 error 발생
let a = 1;
console.log(a);
변수 선언이 함수 선언보다 위로 끌어올려진다.
var a = 1;
function a(){
console.log('123');
}
console.log(a); //1
값이 할당되어 있지 않은 변수의 경우, 함수선언문이 변수를 덮어쓰지만 값이 할당되어 있는 변수의 경우, 변수가 함수선언문을 덮어쓰는 것을 볼 수 있다.
var a = 1;
var b;
function a() {
console.log("123");
}
function b() {
console.log("123");
}
console.log(a); // 1
console.log(b); // function b
var me = 'surim';
function foo () {
alert(me);
var me = 'someone else';
}
foo(); // undefined
본인이 속한 scope내에서 끝까지 올려진다.
var me = 'surim';
function foo () {
var me;
alert(me);
me = 'someone else';
}
foo();
위의 예제의 실행 과정이다. 함수 내의 me
가 Hoisting이 되었지만 아직 할당하기 전에 alert를 함으로 결과는 undefined가 나오게 된다.