호이스팅이 뭐야?
- 자바스크립트의 특이점 중 하나로, 스크립트를 실행하기 전 준비단계에서 var 혹은 function 등 선언문을 찾아 이 변수 혹은 함수를 생성하는 것이다.
호이스팅의 특징
- 이는 마치 선언문이 해당 스코프의 최상단으로 끌어올려지는 것과 같은 효과라서, 코드 작성 순서상으로 선언문이 더 뒤에 있어도 참조 에러(ReferenceError)가 발생하지 않는다.
-
하지만 변수에 무언가를 할당하기 전까진 값이 undefined이다. 즉,
선언
-초기화
-할당
단계 중,선언
과초기화
만 호이스팅 되고,할당
은 호이스팅되지 않는다는 것이다.-
예시
function sayHi() { alert(phrase); var phrase = "Hello"; } sayHi(); // undefined
-
- 참고로, 변수가 함수(by 선언문)보다 더 위로 끌어올려진다.
-
“var와 다르게 let이나 const를 쓰면, 호이스팅이 발생하지 않는다”라고 생각할 수 있는데 이는 사실이 아니다. 물론 let을 쓴 선언문이 더 뒤에 있을 경우, 참조 에러가 발생한다. 스코프의 시작에서 변수의 선언문까지 일시적 사각지대(Temporal Dead Zone; TDZ)에 빠지기 때문이다. 하지만 이게 호이스팅이 발생하지 않아서는 아니다. 선언만 호이스팅되고 초기화부터는 호이스팅되지 않기 때문에 접근을 못할 뿐이다. 아래 예시를 보면 이를 알 수 있다. 호이스팅이 일어나지 않았다면 10이 출력되었어야 했을 거다. 하지만 선언이 호이스팅되다보니 TDZ가 생겨 초기화 전에 액세스할 수 없다는 에러가 뜬다.
let a = 10; { console.log(a); let a = 20; }
함수 표현식과 함수 선언문
함수 표현식
- 실제 실행 흐름이 해당 함수에 도달했을 때 함수를 생성한다. 즉, 실행 흐름이 함수에 도달해야만 그 때부터 해당 함수를 사용(할당, 호출 등)할 수 있다.
-
예시
myFun(); // Error! const myFun = function() { console.log("wow~~"); }
함수 선언문
- 호이스팅으로 인해, 함수 선언문이 정의되기 전에도 호출할 수 있다.
-
예시
myFun(); // wow~~ function myFun() { console.log("wow~~"); }
그럼, var 키워드를 활용한 함수 표현식에서는?
- 이는 함수 표현식이긴 하지만, var를 통해 값으로서 변수에 할당되는 케이스이다. var의 선언/초기화가 호이스팅되어 해당 스코프 내에서는 어디서든 접근할 수 있지만, 함수를 호출할 수는 없다.
[참고]
https://javascript.info/var
https://ko.javascript.info/function-expressions-arrows