호이스팅이란 인터프리터가 모든(함수,변수)선언문의 메모리공간을 선언전에 미리 할당하여 상단으로 올려서 선언문을 유효범위의 최상단으로 옮겨진것처럼 작동하는 자바스크립트의 독특한 특징을 말한다.
✅ 유효범위?
변수에 접근할 수 있는 범위✅ block-level-scope?
{}로 쌓여진 범위, let,const로 변수생성시 유효한 범위.✅ function-level-scope?
function(){}의{}내의 범위, var로 변수생성이 유효한 범위.✅ 유효범위의 최상단?
- 변수가
함수안에 정의: 선언문이함수의 최상단으로 호이스팅 된다.- 변수가
함수밖에 정의: 선언문이전역의 최상단으로 호이스팅 된다.
아래의 코드를 보면는 인터프리터에의해 위에서부터 한줄씩 실행되기때문에 reference error가 나야한다.
console.log(a)
var a =1;
하지만 undefined가 출력된다.

이는 자바스크립트의 엔진은 모든 선언문을 소스코드에서 찾아내 먼저 실행하여 평가한 뒤, 선언문을 제외하고 소스코드를 위에서부터 실행하기 때문이다.
위처럼 변수선언이 위에서부터 코드가 실행되는 시점(런타임)이아닌 그 이전에 실행되기때문에 변수 또는 함수 선언문이 코드의 상단에 선언된것처럼 동작하는것을 호이스팅이라 한다.
자바스크립트 엔진은 변수선언을 선언과 초기화라는 2단계로 수행한다.
var name; //변수 선언
console.log(name) //undefined
한마디로 변수선언은 변수를 초기화하는 구문이다.
말그대로 변수에 값을 할당(저장)하는 것이다. 값을 할당할 때는 할당연산자=을 사용한다.
name ="javaScript" //값의 할당
값의 할당은 변수선언과 함께 한문장으로 단축표현 할 수 있다.
var name = "javaScript"
이렇게 쓰는법만 배워서 선언과 할당이 서로 다른 시점에서 실행되는것을 몰랐다.
자바스크립트 엔진은 이렇게 단축표현을해도 선언과 할당을 2개의 문으로 나누어 따로 실행한다.
변수선언은 런타임 전에 먼저 실행되고, 값의 할당은 코드가 순차적으로 실행되는 런타임에 실행된다.
좀더 쉽게 말하자면 변수선언은 자바스크립트 엔진 구동시 최상단으로 호이스팅이 되고, 값의 할당은 런타임때 실행되기때문에 코드가쓰여지 위치에서 할당된다.(호이스팅 안됨)
호이스팅은 키워드를 사용한 변수선언문이나 함수선언문에서만 발생되기때문에 아래처럼 단순하게 선언만 한경우는 참조에러가 난다.

변수 선언문과 var,let,const, function, function*, class 키워드를 사용하여 선언되는 모든 식별자는 호이스팅이 일어난다.
undefined로 초기화가 동시에 진행된다.
이로인해 var는 의도치않게 변수가 중복되는 경우가 생기는데 이를 방지하기위해 let과 const가 등장하였다.

let은 var과 달리 초기화단계만 이루어지지 않았을뿐 자바스크립트엔진은 이미 선언을 실행해두었고 변수 선언문에 도달했을때 초기화가 일어난다.const는 변수의 선언과 초기화,할당이 모두 동시에 일어나야한다.TDZ(Temporal Dead Zone)라한다.

그래서 let과 같은 결과가 뜬다.
하지만 변수를 var로 선언할 경우 TypeError가 발생한다.

var로 선언하면 초기화가 undefined 로 add가 초기화되는데 호출할때는 함수로 호출을해서 타입에러가 뜬다.
함수 선언식의경우 함수전체가 호이스팅되어 전역으로 선언될 경우, 중복된 이름이 있을수있는데, 함수 표현식을 쓰면 이를 방지할 수 있다.
uninitialized로 초기화 되어 참조(referenceError)를 뱉는다.변수선언이 함수선언 보다 우선순위가 높다.