JavaScript 호이스팅은 인터프리터가 코드를 실행하기 전에 함수, 변수, 클래스 또는 임포트(import)의 선언문을 해당 범위의 맨 위로 끌어올리는 것처럼 보이는 현상을 뜻합니다.
[MDN]
var greeter = "hey hi";
function Test() {
var hello = "hello";
}
다음과 같은 예시를 살펴보자. hello는 함수 범위로 선언되었고, greeter는 전역 범위로 선언된 코드이다. 이때 hello는 Test() 밖에서 사용할 수 없기 때문에 undefined라는 에러를 발생시킨다.
var greeter = "it is 10";
var greeter = "it is 9";
console.log(greeter);
다음과 같이 선언해도 에러를 발생시키지 않으며 greeter는 "it is 9"으로 초기화된다.
console.log (greeter);
var greeter = "say hello"
다음과 같이 선언하게되면 자바스크립트 호이스팅 매커니즘에 따라 변수와 함수 선언이 맨 위로 이동하게 된다. 따라서 위 코드는
var greeter;
console.log(greeter); // greeter is undefined
greeter = "say hello"
와 같이 해석되며 undefined으로 초기화 된다.
이러한 var들의 특징 때문에 많은 개발자들은 많은 오류를 접할 수 있다. 대표적으로 예상치 못하게 재정의가 되더라도 오류를 뱉어내지 않기 때문에 어디에서 초기화가 되었는지 확인할 방법이 없다.
이 때문에 var를 개선한 let과 const의 선호도가 높아졌다.
let english = "abc";
if (english) {
let hi = "hi";
console.log(hi);
}
console.log(hi);
위와 같은 경우에서 if(english)로 묶여 있는 블록 스코프 안에서 hi가 선언되었기 때문에 블록 밖에서 console.log(hi)는
ReferenceError: hi is not defined
에러를 발생시킨다. 그러나 console.log(english)는 같은 블록 스코프에 존재함으로 에러를 발생시키지 않는다.