[자바스크립트]호이스팅(hoisting)
in Devlog on JavaScript
자바스크립트 프로그램이 실행되면 코드가 차례차례 위에서부터 해석될 것이라고 생각하기 쉽다. 거의 옳지만, 가끔 이런 생각은 프로그램의 오류를 일으키기도 한다.
TL;DR 호이스팅 : 선언문이 스코프의 꼭대기로 끌어올려 지는 것
호이스팅
a = 2;
var a;
console.log(a);
위와 같은 코드가 있을 때 출력값은 무엇일까? 프로그램이 순차적으로 실행된다면 쉽게 undefined
가 나올 것이라고 생각할 수 있다. 하지만 실제 실행결과는 2
이다.
자, 그럼 다시 비슷한 코드를 확인해보자.
console.log(a);
var a = 2;
출력결과를 유추할 수 있겠는가? 참조에러? 2? 정답은 undefined
이다.
왜 이런 현상이 발생할까?
변수 호이스팅
우리가 흔히 사용하는 초기화 코드는 자바스크립트에서는 두개의 구문으로 나뉜다.
var a = 2;
//두개의 구문으로 나뉜다.
var a; //선언문
a = 2; //대입문
선언문은 컴파일단계에서 처리된다. 그 이유에 대해서는 스코프에 관한 이야기를 할 때 더 자세히 하도록하자. 그에 반해 대입문은 실행 단계에 처리된다. 그렇기 때문에 우리가 처음 확인한 코드를 해석해보면 다음과 같다.
var a;
a = 2;
console.log(a);
자, 그럼 두번째 코드 스니펫은 어떤 모양이었을까?
var a;
console.log(a);
a = 2;
이처럼 선언문이 코드의 꼭대기로 끌어올려
지는 것을 호이스팅
이라고 한다.
함수 호이스팅
한가지 더 확인해보자. 함수는 그럼 어떻게 될까? 아래의 코드 스니펫을 보면서 이야기 해보자.
foo();
function foo() {
console.log(a);
var a = 2;
}
이건 좀 복잡해 보일 수 있다. 출력값은 무엇일까? 함수는 제대로 실행되고 undefined
가 출력된다. 2번째 코드 스니펫과 같은 원리이다. 좀더 자세히 이해하기 위해 아까 호이스팅의 정의를 선언문이 코드의 꼭대기로 끌러올려지는 것
이라고 했던 것을 정정하자. 선언문이 스코프의 꼭대기로 끌어올려지는 것
이다.
이 코드를 해석하면 아래와 같다.
function foo() {
var a;
console.log(a); //undefined
a = 2;
}
foo();
마치며
간단하게 호이스팅에 대해 알아보았다. 생각보다 어려운 개념은 아니라는 것에 다들 공감할 것이다. 호이스팅은 자주 사람들을 헷갈리게해 프로그램의 오류를 일으키는 요소이다. 하지만 잘 이해하고 사용한다면, 더 멋진 코드를 만들 수 있을 것이다.
+
부록
함수와 변수의 선언문 모두 호이스팅이 된다. 그럼 뭐가 먼저일까?
foo(); // 1
var foo;
function foo() {
console.log(1);
}
foo = function() {
console.log(2);
}
위 코드의 출력값은 1
이다. 한가지 퀴즈를 내고 글을 마치려한다. 아래 코드의 출력값은 무엇일까? 실행해보기전에 충분히 고민해 답을 내보길바란다.
foo();
function foo(){
console.log(1);
}
var foo = function() {
console.log(2);
};
function foo() {
console.log(3);
}