호이스팅이란 인터프리터가 모든(함수,변수)선언문의 메모리공간을 선언전에 미리 할당하여 상단으로 올려서 선언문을 유효범위의 최상단으로 옮겨진것처럼 작동하는 자바스크립트의 독특한 특징을 말한다.
✅ 유효범위?
변수에 접근할 수 있는 범위✅ 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)를 뱉는다.변수선언이 함수선언 보다 우선순위가 높다.