본문 바로가기

■ 프로그래밍/JavaScript

호이스팅 - 변수, 함수

호이스팅(Hoisting)이란 변수의 선언을 유효 범위(Scope)의 최상단으로 끌어올리는 것을 말한다. 

만약 변수가 함수 외부에 정의되어 있다면 전역 영역의 최상위로, 함수 내부에 정의되어 있다면 함수의 최상위로 변수가 끌어올려진다(호이스팅된다).

 

변수 호이스팅

console.log(a); // output: Uncaught ReferenceError: a is not defined

만약 아무것도 선언 되지 않은 상태에서 바로 a를 콘솔로 찍으면 ReferenceError가 뜬다. 

console.log(b); // output: undefined
var b;

하지만 콘솔 밑에 바로 b를 선언하면 이번에는 에러가 아니라 undefined가 뜬다. 이는 변수 b를 아래에서 최상단으로 끌어왔기 때문에 변수가 없는 것이 아니라, 있지만 아직 선언되지 않은 상태라는걸 나타낸다.

console.log(c); // output: undefined
var c = 'hello'; 

밑에 c를 'hello'라 할당하여도, console위에 아직 할당되지 않았기 때문에 c는 undefined로 출력된다. 이렇듯 변수를 최상위로 끌어 올리는 행위를 호이스팅이라 부르며, 변수의 선언과 할당이 분리되는 것이라 볼 수 있다. 

 

함수 호이스팅

함수의 호이스팅도 변수 호이스팅과 원리는 같다. 

funcOne();
function funcOne() {
	console.log("First one");
}
// output: First one

funcOne이 무엇인지 선언되기 전에 먼저 불렀지만, 함수 호이스팅에 따라 하단에 선언된 함수를 전역 영역의 최상위로 끌어올려 console 내용을 출력하고 있다. 

funcTwo();
console.log(funcTwo); // output: Uncaught ReferenceError: funcTwo is not defined

반대로 아직 선언되지 않은 상태에서 funcTwo()를 호출했기 때문에 변수 호이스팅과 같이 ReferenceError가 뜬다. 

 

만약 함수를 호출하고 하단에 함수 선언식이 아니라 함수 표현식으로 한다면 결과값은 어떻게 될까?

결과는 밑에와 같이 TypeError가 뜬다.

funcTwo();
var funcTwo = function() {
	console.log("Second one");
}
// output: Uncaught TypeError: funcTwo is not a function

이는 funcTwo를 함수가 아닌 변수로 인지하기 때문이다. 왜냐하면 '호이스팅은 변수의 선언과 할당이 분리'된다. 

따라서 변수 형태로 함수를 할당할 경우, 무조건 함수가 만들어진 후에 호출해야 한다.