var
로 선언된 표현식이나 함수 선언문 등을 실행 단계에서 해당 스코프의 맨 위로 끌어 올리는 것을 뜻한다.
자바스크립트의 변수 생성과 초기화의 작업이 분리되어 진행되기 때문이다.
ex)
var result = sum(2,3);
var sum = function(num1, num2) {
return console.log(num1+num2);
} // TypeError: sum is not a function
위의 예시를 실행시켜보면 TypeError: sum is not a function
라는 에러가 발생한다.
그 이유는 아래와 같다.
ex) 실행시
// var로 선언된 변수들이 맨위로 끌어올려지는데, 이때는 변수 선언만 된다.
var result = undefined;
var sum = undefined;
// 변수 선언이 된 뒤 값 초기화가 이루어진다.
result = sum(2,3);
sum = function(num1, num2) {
return console.log(num1+num2);
} // TypeError: sum is not a function
그럼 함수 선언문이나 함수 표현문의 예시를 통해 호이스팅이 일어나는지 비교해보자.
ex)
console.log(test( ));
console.log(testValue( ));
function test(){
return "test";
} // 함수 선언문
var testValue = function(){
return "testValue";
} // 함수 표현문
위의 예시를 실행해보면 아래와 같은 결과가 나온다.
console.log(test( )); // 'test'
console.log(testValue( )); // TypeError: testValue is not a function
function test(){
return "test";
} // 함수 선언문
var testValue = function(){
return "testValue";
} // 함수 표현문
함수 선언문은 코드를 실행할 때 함수를 포함하는 스코프 최상단으로 끌어올려지기 때문에 함수 선언 전에 함수를 실행해도 에러가 발생하지 않는다.
하지만 함수 표현문은 변수를 통해서 함수를 참조하기 때문에 호이스팅이 발생하지 않아 에러가 발생하는 것이다.
그 이유는 변수를 선언했다고 해도 그 값까지는 끌어올려지지 않기 때문이다.
변수 키워드 중에서도 호이스팅이 일어나지 않는 선언들이 있다.
ex)
console.log(test1);
console.log(test2);
let test1 = "let value";
const test2 = "const value";
ex) let의 경우
console.log(test1); // ReferenceError: test1 is not defined
// console.log(test2);
let test1 = "let value";
const test2 = "const value";
ex) const의 경우
// console.log(test1);
console.log(test2); // ReferenceError: test2 is not defined
let test1 = "let value";
const test2 = "const value";
let과 const는 블록 스코프이기 때문에 우선 선언된 변수와 상수는 TDZ(Temporal Dead Zone, 임시 접근 불가구역) 구역에 배치되었다가 선언이 실행된 후에 TDZ에서 제거되어 사용 가능한 상태가 된다.