호이스팅이란
function test() {
console.log(test); // undefined 출력
var test = 'hello';
}
위 코드에서 test가 선언되기 전에 호출을 했음에도 오류가 나지 않는다. 다만 undefined 가 출력될 뿐이다. 이는 자바스크립트에서 함수 내에 선언된 변수/함수등을 최상단으로 끌어올려 선언하기 때문이다. 이를 호이스팅이라 한다.
즉 호이스팅이 일어나서 다음 코드와 동일하게 동작한다.
function test() {
var test;
console.log(test);
var test = 'hello';
}
function안의 변수들은 모두 선언 위치와 상관없이 function 내에서 scope를 유지하게 된다. 이를 function scope를 가진다고 한다.
처리방식
- 자바스크립트 Parser가 함수 실행전에 함수를 한번 훑어서 필요한 변수/함수 정보를 기억하고 있다가 실행한다.
- 코드 자체가 끌어올려지는 것은 아니고 Parser가 내부적으로 그렇게 처리하는 것이다.
- 때문에 실제 메모리에 변화는 없다.
호이스팅 대상
- var로 선언된 변수/함수만 끌어올려지며 할당은 끌어올려지지 않는다. 즉 undefined 인 상태로 올려진다.
- let/const, 함수표현식에선 호이스팅이 발생하지 않는다.
// 함수 선언문 - 호이스팅O (오류 안남, 콘솔로그 'myFunc' 출력됨)
function test() {
myFunc();
function myFunc() {
console.log('myFunc');
}
}
// 함수 표현식 - 호이스팅X (오류 발생 Uncaught TypeError: myFunc is not a function)
// myFunc은 undefined로 지정됨.
function test() {
myFunc();
var myFunc() = function() {
}
}
호이스팅 순서
동일 이름의 함수/변수가 있을 땐 '변수 선언 - 함수 선언 - 변수 할당' 순으로 진행된다.
function test() {
function hello() {
};
var hello = 'hello';
console.log(typeof hello);
}
호이스팅이 되면 다음 코드처럼 동작한다
function test() {
var hello;
function hello() {
};
hello = 'hello';
console.log(typeof hello); // 'string' 출력
}
중간에 변수 할당이 안일어 났다면
function test() {
var hello;
function hello() {
};
// hello = 'hello';
console.log(typeof hello); // 'function' 출력
}
알아두기
코드의 가독성과 유지보수를 위해 왠만하면 호이스팅이 안일어나게 하는게 좋다.
- var을 사용하는 대신 ES6의 let/const를 사용한다.
- var- function scope(호이스팅O), let/const- block scope(호이스팅X)
- var- 중복 선언 가능, let/const- 중복선언 불가(에러발생)
- 함수/변수를 최상단에 선언하여 호이스팅으로 인한 스코프 꼬임이 발생하지 않도록 한다.
참고 사이트