호이스팅(Hoisting)은 함수 안에 있는 선언들을 모두 끌어올려 해당 함수 유효 범위의 최상단에 선언하는 것을 말합니다.
var 변수 선언과 함수선언문에서만 호이스팅이 일어납니다.
함수선언문은 호이스팅이 발생해 위로 올려지지만 함수표현식은 올려지지 않습니다.
변수에 할당된 함수표현식은 끌어올려지지 않기에 그대로 변수의 스코프 규칙을 따르는 것에 주의하셔야 해요.
함수선언문은 코드를 구현한 위치와 관계없이 자바스크립트의 특징인 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어올려집니다.
함수표현식은 함수선언문과 달리 선언과 호출 순서에 따라 정상적으로 함수가 실행되지 않는 경우가 있을 수 있습니다.
📍undefined 가 나타나는 이유
var로 선언한 변수의 경우 호이스팅 시 변수의 값을 undefined로 초기화합니다. 변수를 선언하기 전에 사용할 수 있지만 값은 나오지 않는 이유입니다.
✍🏻 호이스팅을 설명할 땐 주로 "변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는" 것으로 말하곤 합니다.
같은 이름의 var변수 선언과 함수 선언에서의 호이스팅
-변수 선언이 함수 선언보다 위로 끌어올려진다.
-값이 할당되어 있지 않은 변수와 값이 할당되어 있는 변수에서의 호이스팅
값이 할당되어 있지 않은 변수 => 함수선언문이 변수를 덮어쓴다.
값이 할당되어 있는 변수 => 변수가 함수선언문을 덮어쓴다.
코드의 가독성과 유지보수를 위해 가급적 호이스팅이 일어나지 않도록 주의하는 것이 좋습니다.
함수와 변수를 가급적 코드 상단부에 적어 선언하면 호이스팅으로 인한 스코프 꼬임은 방지할 수 있겠죠.
그래서 let / const를 쓰는 이유입니다.
let / const도 호이스팅이 일어나긴 하지만 TDZ(temporal death zone)으로 값을 할당하기 전에는 사용할 수 없도록 죽은 공간으로 만드는 것입니다. TDZ로 잠재적인 버그를 줄일 수 있는 것이죠.
var를 쓰면 혼란스럽고 쓸모 없는 코드가 생길 수 있는데 왜 var와 호이스팅을 이해해야 할까요?
ES6를 어디서든 쓸 수 있으려면 아직 시간이 더 필요하므로 ES5로 트랜스컴파일을 해야합니다. 따라서 아직은 var가 어떻게 동작하는지 이해하는 것이 필요합니다.