호이스팅이란
변수 혹은 함수의 선언 구가 호출을 한 위치보다 아래에 있더라도 끌어올리는 현상을 말한다.
- 전역 범위(global scope) : 전역 범위에서는 스크립트 단위에서 최상단으로 끌어올려 진다.
- 함수 범위(function scope) : 함수 범위에서는 해당 함수의 최상단으로 끌어올려 진다.
변수 호이스팅
age = 6;
var age;
age가 먼저 선언되지 않아도 오류 없이 사용이 가능하다.
console.log(age); // undefined
var age = 11;
console.log(age); //11
주의) 할당된 내용은 올라가지 않고 선언 구만 올라간다.
그 결과 첫 번째 console.log는 정의되지 않았다는 undefined가 찍히게 되지만 두 번째 console.log는 할당된 값이 표현된다.
선언 구는 자바스크립트 엔진 구동 시 최우선으로 해석하므로 호이스팅 되고 (선언과 초기화를 한 번에 한다.),
할당 구는 런타임 과정에서 이루어지기 때문에 변수에 할당문에 도달해야 할당되기 때문에 호이스팅 되지 않는다.
이 현상은 var에서만 일어난다. let,const(ES6선언)은 일어나지 않는다.
console.log(foo); // ReferenceError: foo is not defined
let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined
foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1
let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.
즉, 스코프에 변수를 등록(선언단계)하지만 초기화 단계는 변수 선언문에 도달했을 때 이루어진다.
따라서 스코프의 시작 지점부터 초기화 시작 지점까지는 변수를 참조할 수 없다.
이는 변수가 아직 초기화되지 않았기 때문이다. 다시 말하면 변수를 위한 메모리 공간이 아직 확보되지 않았기 때문이다.
스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 ‘일시적 사각지대(Temporal Dead Zone; TDZ)’라고 부른다.
결국 let도 호이스팅은 일어나지만 TDN에 빠지게 되어 호이스팅이 일어나지 않아 보인다. (참조적 오류가 발생)
함수 호이스팅
hoisting(); // 호이스팅!!
NoHoisting(); // Uncaught TypeError: NoHoisting is not a function
function hoisting(){
console.log("호이스팅!!");
}
var NoHoisting = function(){
console.log("호이스팅 안된다");
}
함수 선언문은 호이스팅 되어 호이스팅!!
가 찍히지만
함수 리터럴 방식은 호이스팅이 되지 않는다. (변수 호이스팅 발생)
참고자료 : https://poiemaweb.com/es6-block-scope
https://asfirstalways.tistory.com/197