console.log(score); //undefined
var score; //변수 선언문
위 코드를 보면 변수 선언문보다 변수를 참조하는 코드가 앞에 있다. 자바스크립트는 한줄 씩 차례대로 읽어나가는 특성이 있다.
하지만 위 코드를 보면 참조에러가 발생하지 않고 undefined가 출력이 된다.
이유는 변수 선언이 소스코드가 한 줄 씩 순차적으로 실행되는 시점. 즉 런타임이 아니라 그 이전 단계에서 먼저 실행되기 때문이다.
위 코드를 보았듯이 자바스크립트 엔진은 변수 선언을 포함한 모든 선언문(변수 선언문, 함수 선언문 등)을 소스코드에서 찾아내 먼저 실행한다. 그리고 소스코드의 평가 과정이 끝나면 비로소 변수 선언을 포함한 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행한다.
이게 자바스크립트의 문제점이다.???!!!(어디서 들은거 같다.)
호이스팅이란 "끌어올린다" 라는 뜻으로 변수 및 함수 선언문이 스코프 내의 최상단으로 끌어올려지는 현상 을 말한다. 여기서 주의할 점은 "선언문" 이라는 것이며 "할당문"은 끌어올려지지 않는다.
console.log(a);
var a = 2;
컴파일러는 자바스크립트 엔진이 인터프리팅(Interpreting)을 하기 전에 컴파일을 하는데 이 때, var a = 2;
를 2개의 구문으로 본다.
var a
a = 2
var a
는 변수 선언문으로 컴파일을 할 때 처리하고, a = 2
는 실행할 때까지 내버려둔다. 따라서, 변수 a는 호이스팅 되고 콘솔에는 다음과 같은 결과가 나온다.
undefined
함수 선언문의 경우도 호이스팅 된다.
func();
function func() { console.log('함수 호이스팅'); }
함수 호이스팅
함수 호이스팅에서 주의할 점이 더 있다.
func();
var func = function() {}
여기서는 변수 func의 호이스팅이 발생해서 참조할 수는 있기 때문에 ReferenceError가 발생하지 않지만 그 값이 undefined
이기 때문에 TypeError가 발생한다.
func();
var func = function(){ console.log('변수 호이스팅') }
function func() {
console.log('함수 호이스팅');
}
동일한 이름으로 함수 선언문과 변수 선언문(= 함수표현식)이 있지만 함수 선언문의 호이스팅이 먼저이기 때문에 결과는 다음과 같다.
함수 호이스팅