인터프리터가 코드를 실행하기 전에 함수, 변수, 클래스 또는 임포트(import)의 선언문을 해당 범위의 맨 위로 끌어올리는 것"처럼 보이는" 현상
- mdn [ hoisting ]
즉, 호이스팅은 변수나 함수 등을 실제로 끌어올리는 것이 아님
1. 선언 단계 (Declaration Phase)
- 변수를 실행 컨텍스트의 환경 레코드에 기록
2. 초기화 단계 (Initialization Phase)
- 환경 레코드에 기록된 변수를 위한 공간을 메모리에 확보
- 이 단계에서 변수는undefined
로 초기화
3. 할당 단계 (Assignment Phase)
-undefined
로 초기화된 변수에 실제 값을 할당
선언 단계와 초기화 단계가 한 번에 이루어짐
선언 단계에서 환경 레코드에 "Key = 변수명, Value = undefined
" 로 매핑
변수 선언문 이전에 변수에 접근해도 에러가 아닌,
undefined
를 반환
선언 단계와 초기화 단계가 분리되어, 초기화는 변수 선언문에 도달했을 때 이루어짐
선언 단계에서 환경 레코드에 "Key = 변수명 , Value = <uninitialized>
" 로 매핑
변수 선언문 이전에 변수에 접근 시,
Reference Error
가 발생
이를 일시적 사각지대 (TDZ) 라고 함
함수는 총 두 가지 방식으로 정의할 수 있음
1. 함수 선언
2. 함수 표현
이 중에서, 1. 함수 선언 방식만 정상적으로 동작함.
var
로 표현한 함수는 왜 ?
- 함수 정의에var
를 사용할 경우, 함수 호이스팅이 아닌 변수 호이스팅 규칙을 따름
- 변수는 호이스팅 시undefined
로 초기화 되거나 초기화 되지 않음
= 이 때,undefined
는 함수가 아니기 때문에 에러 발생 (TypeError)
// 함수 선언문은 정상 작동
console.log(square(5)); // `25`
function square(n) {
return n * n;
}
// 에러 발생
console.log(square); // ReferenceError: 초기화 되기 전에는 `square`에 접근할 수 없습니다.
const square = function (n) {
return n * n;
};
// 함수 표현식(var) 또한 에러 발생
console.log(square()); // is not a function 에러 표시
var square = function() {
return n * n;
};
변수가 선언 되었으나, 아직 초기화되지 않은 상태
let
과 const
로 선언한 변수들이 거쳐가는 공간ReferenceError
가 발생.