결국
hoist란 무언가를 '끌어[들어]올리다'라고 말할 수 있다.
호이스팅은 ECMAScript 2015(ES6)에서 등장하였다.
파서가 코드 실행 전에 초기화가 아닌 선언만 끌어올린다.
선언을 둘러싼 함수의 최상단이나 전역 범위(global scope)로 끌어올려진다.
console.log("물은 역시 " + water);
var water = "삼다수";

실행해보면 에러가 아닌 undefined로 출력되는 걸 확인할 수 있다.
호이스팅이 일어난 후 코드는 다음과 같이 해석할 수 있다.
var water;
console.log(water);
water = "삼다수";
ex) var vs let
varNum = 6;
varNum += 7;
var varNum;
console.log("var로 선언한 varNum : " + varNum);
letNum = 6;
letNum += 7;
let letNum;
console.log("let으로 선언한 letNum : " + letNum);

var로 선언한 varNum변수는 호이스팅이 일어나서 콘솔에 찍히지만, let으로 선언한 letNum을 사용하자 에러가 발생한다.
모든 선언부는 호이스팅이 된다. var 선언부는 undefined로 초기화되는 반면 let, const 선언부는 uninitalized 상태로 남아있다.
let, const 변수는 할당 할때만 초기화된다. 즉 할당이 이루어지기 전에 자바스크립트 엔진이 변수에 접근할 수 없다. 선언과 초기화 전까지 Temporal Dead Zone이라고 부른다.
ex) 함수 선언문 vs 함수 표현식
hoisted();
function hoisted() {
console.log("함수 선언문 호이스팅");
}
notHoisted();
var notHoisted = function() {
console.log("함수 표현식");
}

호이스팅은 아래와 같이 일어난다. 결국 notHoisted 변수는 함수가 아니기 때문에 에러가 난다.
var notHoisted;
notHoisted(); ///TypeError
notHoisted = function() {
console.log("함수 표현식");
}
undifined나 reference error를 피하기 위해서 항상 스코프 영역 내 최상단에 선언과 초기화를 해주는 것을 권장한다.
https://developer.mozilla.org/ko/docs/Glossary/Hoisting
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/var
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/function
https://blog.bitsrc.io/hoisting-in-modern-javascript-let-const-and-var-b290405adfda