2019. 06. 09 수정


JS는 다른언어와 비교했을 때 변수 scope와 관련하여 특별한 성질이 있습니다.

  • C, Java
    • 변수를 사용하거나, 어떤 함수를 호출하기 위해서는 사용하기 전에 미리 변수, 함수가 선언되어 있어야 합니다.
  • JS
    • 변수, 함수를 나중에 정의하더라도 즉시 사용할 수 있다는 특징이 있습니다.

JS의 이러한 특징을 호이스팅이라고 하는데, 이번 글에서는 호이스팅에 대해 알아보도록 하겠습니다.





1. 변수 호이스팅

변수 호이스팅이란 변수의 정의가 그 범위에 따라 선언과 할당으로 분리되는 것을 의미합니다

  • 변수가 함수 내부에 작성이 되었다면, 함수 내부의 최상위에서 선언된 것과 같으며,
  • 변수가 함수 외부에 작성이 되었다면, 전역 컨텍스트의 최상위에서 선언된 것과 같습니다.

중요한 것은 함수 내부/외부 어떤 경우라도, 변수가 선언만 된 것이고 할당된 것이 아니라는 점이죠.


예제를 살펴보겠습니다.

let foo = function(){
console.log(goo); // undefined
var goo = "hello";
console.log(goo); // hello
};

foo();

C, Java 같은 경우에는 goo 변수를 선언하기 전에, console.log(goo) 처럼 goo 변수를 사용하려 했으므로 오류가 발생해야 합니다.

그러나 JS는 goo 변수가 나중에 선언되었지만 먼저 선언된 것으로 간주하고 undefined를 출력합니다.

이것을 호이스팅이라 하는데, 위의 함수는 JS 내부적으로 다음과 같이 바뀝니다.

let foo = function(){
var goo;
console.log(goo); // undefined
goo = "hello";
console.log(goo); // hello
};

즉, 호이스팅의 정의대로 선언과 할당이 분리됩니다.



그런데 최신 JS 문법에서는 변수 선언 시, var 대신 let을 주로 사용합니다. ( let 선언 - 참고 )

let foo = function(){
console.log(goo); // error : goo is not defined
let goo = "hello";
console.log(goo); // hello
};

foo();

let을 사용할 경우에는 C, Java처럼 오류메시지가 출력됩니다.





2. 함수 호이스팅

함수 호이스팅이란 함수 선언문 형태로 정의된 함수의 유효 범위는 스크립트의 맨 처음에 선언된 것으로 간주한다는 의미입니다.

console.log(add(3,5));

function add(a,b){
return a + b;
}


아직 add() 함수를 정의하지 않았는데 add() 함수를 호출해서 정상적으로 실행이 되었습니다.

이것을 함수 호이스팅이라고 합니다.


그런데 이런식으로 함수 선언문으로 함수를 정의하면 함수 호이스팅에 의해 코드의 구조가 꼬일 수 있으므로, 함수 표현식을 이용해서 함수를 정의할 것을 권고하고 있습니다.

console.log(add(3,5));  // error : add is not defined

let add = function(a,b){
return a + b;
}


이처럼 함수 표현식으로 함수를 정의하면 함수 호이스팅이 일어나지 않습니다.




이상으로 호이스팅에 대해 알아보았으며, 이를 정리하면 다음과 같습니다.

  • 호이스팅
    • 쉽게 말하면 선언 부분이 최상단으로 끌어올려지는 동작 방식을 의미합니다.
  • 변수 호이스팅
    • 변수의 선언과 할당이 분리된다는 개념
  • 함수 호이스팅
    • 함수 선언문 형태로 정의한 함수는 스크립트 맨 처음부터 실행된다는 개념