먼저 호이스팅에 대해 알아보기 전 코드 실행 시에 변수가 처리되는 법을 알아보자.
호이스팅
- 변수가 선언된 시점보다 앞에서 사용되는 현상이다.
- 이는 var 변수가 생성 단계에서 undefined로 초기화되는 것이 원인이다.
- 함수는 생성 단계에서 함수 전체가 저장되므로 뒤에서 선언되어도 호출이 가능하다.
console.log(callMe()) // undefined
var x = 10
console.log(callMe()) // 10
function callMe(){ // 뒤에서 선언되어도 호출이 가능
return x
}
ReferenceError
가 발생한다.// ReferenceError: Cannot access 'a'
// before initialization
console.log(callMe()) // 생성 단계에서 x를 위한 공간은 할당되지만 값은 초기화되지 않는다.
let x = 10
console.log(callMe()) // 10
function callMe() {
return x
}
var, let, const는 모두 변수를 선언하는 키워드
var, let은 변수에 재할당이 가능하지만, const는 재할당이 불가능
var는 함수 스코프, let과 const는 블록 스코프 변수
varFor에서 i는 varFor 함수 범위에 존재하는 변수이다.
따라서 setTimeout이 호출될 때, i는 for블럭이 끝난 시점에 소멸하지 않는다.
letFor에서 i는 for 블럭 안에 존재하는 변수이다.
각 for block이 실행되고 i는 소멸한다. 다만 이 경우 각 화살표 함수의 closure에 저장된다.
function varFor() {
for (var i = 0; i < 3; ++i) {
setTimeout(() => console.log("i: ", i), 0);
}
}
function letFor() {
for (let i = 0; i < 3; ++i) {
setTimeout(() => console.log("i: ", i), 0);
}
}
varFor(); // 3 3 3
letFor(); // 0 1 2