[JavaScript] 2. 호이스팅
2. 호이스팅
이전 장에서 JS의 기본적인 변수에 대해 알았다면 이제 JS가 동작하는 원리는 호이스팅을 이번 장에서 알아보도록 하겠습니다.
호이스팅란?
프로그래밍 언어를 사용한다면 함수와 변수를 정말 많이 사용할 것입니다. JS에서 호이스팅은 이러한 변수나 함수 등이 저장 공간을 미리 만듭니다.
호이스팅: 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다.
즉 변수를 선언 + 초기화 하는 과정을 분리해서 선언만 스코프의 맨 위로 올려서 실행하는 것을 말하는데 이게 글로는 이해하기 힘들지만 예를 들면 쉽게 설명할 수 있습니다. 일단 아래는 JS의 변수 선언 당 실행되는 호이스팅 방식입니다.
var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다.
반면 let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.
코드 예시
<함수 선언>
JS는 함수 실행 이전에 함수 선언에 대한 메모리를 먼저 할당해서 자동적으로 선언을 스코프의 맨 위로 올려줍니다.아래의 예시는 기본적으로 우리가 코드를 작성하는 방식인 함수 선언 -> 함수 호출의 방식이라면
function Name(name) {
console.log(name);
}
Name("호랑이"); // 실행 결과 : "호랑이"
2번째의 예시 처럼 먼저 함수호출 -> 함수 선언 식으로 코드를 작성해도 호이스팅으로 인해 자동적으로 함수 선언을 맨 위로 올려주는 식으로 동작하기 때문에 코드가 실행됩니다.
Name("호랑이");
function Name(name) {
console.log(name);
}
<변수 선언>
JS에서 호이스팅이 중요한 것은 변수를 선언할 때 있습니다. JS는 변수의 선언 만 호이스팅 합니다. 즉
변수 선언 + 초기화의 과정에서 선언만 위로 올려 변수를 저장할 메모리를 할당한다는 이야기입니다.
아래의 예를 보면 var의 경우 변수 선언시 자동으로 값이 없다는 undefined라는 것으로 호이스팅이 진행되기 때문에 초기화 과정에 상관없이 undefined가 출력되게 됩니다.
console.log(num); // undefined 출력
var name; // 변수 선언
name = "호랑이"; // 변수 초기화
만약 선언까지 없다면 아래와 같은 결과가 나오게 됩니다.
console.log(name); // ReferenceError
name = "호랑이"; // 변수 초기화
그렇다면 아래와 같은 예가 나오면 결과가 어떻게 나올까요?
function b(){
for(var i=0;i<10;i++){
}
return i;
}
console.log(b());
결과는 10이 나오게 됩니다. 위에서 설명드린 것 처럼 var의 경우 변수의 선언은 스코프의 맨 위로 올라오기 때문입니다. 즉 위의 코드는 아래의 코드와 동일하다고 볼 수 있습니다.
function b(){
var i = undefined;
for(var i=0;i<10;i++){
}
return i;
}
console.log(b());
const, let의 호이스팅
위의 var과 다르게 const와 let은 호이스팅이 발생할 때 선언이 맨위의 스코프로 올라오는 것은 맞지만 undefined로 초기화가 진행되지 않습니다. 따라서 함수 b를 let으로 바꾸게 될 경우 에러가 발생합니다.
이는 블록 내부에 i를 초기화 시키지 않았기 때문에 발생되는 에러입니다. 즉 for 안의 i는 for이 끝나는 즉시 참조 할 수 없는 i로 바뀌기 때문에 return에 들어갈 i가 아직 초기화 되지 않는 에러가 발생하는 것입니다.