자바스크립트를 공부하는 사람들은 호이스팅이라는 용어를 접해본 경험이 있을 것이다. 정의를 내려보기 전에, 아래의 예제를 한번 살펴보도록 하자.
function greeting() {
console.log('hello');
}
greeting();
greeting 함수를 호출 할 때, 예상대로 hello 문자열이 console에 기록이 될 것이다.
하지만 함수를 선언하기 전에 실행하면 어떻게 될까?
greeting();
function greeting() {
console.log('hello');
}
위 예시는 신기하게도 처음 예시와 동일하게 hello 문자열을 콘솔창에 기록한다.
이것이 바로 호이스팅이 동작하는 방식이다.
대부분 이 호이스팅 동작 방식을 설명할 때, 선언한 변수와 함수를 실행 컨텍스트 최상단으로 끌어올린다고 설명한다. 이 말도 맞는 말이지만, 코드 단계에서는 어떠한 이동도 발견되지 않는다. 가장 중요한 점은 함수와 변수 선언부는 컴파일 단계에서 메모리에 추가된다는 점이다.
위 예제들의 함수 선언 구문은 컴파일 단계에서 메모리에 추가됐으므로 실행 컨텍스트 내에서 이 함수 선언 구문에 접근하고 실행할 수 있는 것이다.
일반적으로 우리는 변수를 선언하고 초기화한 다음 변수를 사용하려고 할 것이다.
var a = 3;
console.log(a);
// 3
하지만, 아래와 같이 변수를 선언하면 어떻게 될까?
a = 3;
console.log(a);
var a;
// 3
아래의 예시는?
console.log(a);
var a = 3;
// undefined
3을 예상했겠지만, undefined가 출력됐다.
왜 이런 현상이 발생했을까..? 그 이유는 자바스크립트는 오직 선언문만 끌어올린다(호이스팅한다). 초기화는 호이스팅되지 않는다.
우리가 만약 선언과 초기화를 동시에 한다면, var a = 3;에서 var a;만 상단으로 호이스팅된다.
자바스크립트에서 변수는 선언만하고 초기화를 하지 않는다면, 자동으로 undefined를 할당한다.
아래의 예제는 똑같이 undefined를 출력한다. (선언문만 호이스팅하고, 초기화는 호이스팅되지 않는다.)
console.log(c);
var c = 3;
// undefined
var d;
console.log(d);
d = 3;
// undefined
이러한 자바스크립트의 특성때문에, 변수들은 실행컨텍스트 최상단에 선언하는 것이 바람직한 방법이다. 이러한 방법은 의도치않은 동작을 막을 수 있는 좋은 습관이다. (실행컨텍스트 최상단에 변수 선언과 초기화를 같이 해주는 것이 가장 깔끔한 방법이라고 생각한다. 코드가 직관적이고, 의도를 파악하기 쉽기 때문 + 의도치않은 동작까지 막을 수 있음)