hoist (verb) : raise (something) by means of ropes and pulleys. ( 물체를 밧줄이나 도르래로 들어올리다.)
함수가 실행되기 전, 함수 안에 필요한 변수 값을 모두 모아서 유효 범위 최상단에 선언하는 행위.
var 변수 선언과 함수 선언문에서만 호이스팅이 일어난다.
코드의 위치에 관계 없이, 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어 올려진다.
위와 달리, 호출 순서에 따라 함수가 실행 되지 않을 수도 있다. 함수 표현식에서는 선언과 할당의 분리가 발생한다.
함수 표현식 선언이 호출보다 위에 있는 경우 → 정상 출력
함수 표현식 선언이 호출보다 아래 있는 경우 (var 변수에 할당) → TypeError
함수 표현식 선언이 호출보다 아래 있는 경우 (const / let 변수에 할당) → Reference Error
일시적 사각지대 (Temproal Dead Zone; TDZ)
변수는 다음 3단계로 이루어진다.
선언 : 변수를 실행 컨텍스트의 변수 객체에 등록한다. 스코프는 변수 객체를 참조한다.
초기화 : 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보한다. 변수는 undefined 상태.
할당 : undefined로 초기화된 변수에 실제 값을 할당.
여기서, var로 선언된 변수는 선언과 초기화가 한번에 이루어진다. 따라서, 변수 선언문 이전에 접근하여도 스코프에 변수가 존재하기 때문에 에러가 발생하지 않고 undefined를 반환한다. 이후 할당문에 도달하면 값이 할당된다. ( 변수 호이스팅 )
이와 달리, let으로 선언된 변수는 선언과 초기화가 분리되어 진행된다. 즉, 스코프에 변수를 등록해도 초기화는 변수 선언문에 도달했을 때 이루어진다. 때문에, 초기화 이전에 변수에 접근하면 Reference Error가 발생한다. 스코프 시작 지점부터 초기화 시작 지점까지의 변수 참조가 불가능한 구간을 '일시적 사각지대'라고 부른다
같은 이름의 var 변수 선언과 함수 선언에서의 호이스팅
코드의 가독성과 유지보수를 위해 호이스팅이 일어나지 않도록 한다.
→ 함수 선언문보다 let / const를 이용한 함수 표현식을 쓰자.
var 변수는 호이스팅이 일어나 혼란스러운 코드가 될 수 있다. 되도록 쓰지 말자.
참고 자료
[javascript] 호이스팅 (hoisting) 이란? - ojava
[JavaScript] 호이스팅(Hoisting)이란 - heejeong Kwon
let, const와 블록 레벨 스코프 - Poiemaweb