hoist
라는 단어의 사전적 정의는 '끌어올리기' 이다. 자바스크립트에서 hoist
되는 것은 변수이다. var
키워드로 선언된 모든 변수는 hoist
된다.
즉, 코드의 라인 순서와 관계없이 함수 선언식(함수 표현식 X)과 변수를 위한 메모리 공간을 먼저 확보한다.
hoist
란 변수의 정의가 그 범위에 따라 선언과 할당으로 분리되는 것을 의미한다.
우선, 선언(Declaration
)과 할당(Assignment
)을 이해해보자. 이때 끌어올려지는 것은 선언이다.
function getX() {
console.log(x); // undefined
var x = 100;
console.log(x); // 100
}
getX();
다른 언어라면, 변수 x를 선언하지 않고 출력하려 한다면 오류가 발생한다.
하지만 자바스크립트에서는 undefined
를 출력하고 넘어간다.
var x = 100;
구문에서 var x;
를 hoist
하기 때문이다.
따라서, 작동 순서에 맞게 코드를 재구성하면 다음과 같다.
// 순서 재구성
function getX() {
var x; // hoist
console.log(x);
var x = 100;
console.log(x);
}
getX();
hoisting
된다.hoisting
되지 않는다.함수가 자신의 위치와 상관없이 함수 선언문 형태로 정의된 함수의 유효범위는 전체 코드의 맨 처음부터 시작한다. 즉, 함수 선언이 함수 실행 부분보다 뒤에 있더라도 자바스크립트 엔진이 함수 선언을 끌어올리는 것(hositing
)을 의미한다.
단, 함수 hoisting
은 함수를 끌어올리지만 변수의 값은 끌어올리지 않는다.
아래는 함수 선언식이다.
foo();
function foo() { // 함수 선언식
console.log('hello');
};
이를 재구성하게 되면 어떻게 될까?
function foo() { // 함수 선언식
console.log('hello');
};
foo(); // hello
다음과 같이 함수 선언식이 hoisting
됐다.
즉, foo()
에 대한 선언을 hositing
하여 global 객체에 등록시키기 때문에, 에러가 아닌 hello가 출력된다.
그러면 함수 리터럴을 할당하는 표현식이라면 어떻게 될까?
foo();
var foo = function() { // 함수 표현식(할당 구문)
console.log('hello');
};
이를 재구성 하면 다음과 같다.
var foo;
foo(); // Uncaught TypeError: foo is not a function
foo = function() { // 함수 표현식
console.log('hello');
};
foo()
는 hoisting
되지 않으며 그렇기 때문에 런타임 환경에서 Type Error
이 발생한다.
즉, 함수의 이름(변수)인 foo
만 hoisting
이 되고, 할당 구문은 hoisting
되지 않는다.
동일한 이름의 변수와 함수를 선언하는 경우 우선순위가 존재한다.
var foo = "Hello World";
function foo() {
console.log("I'm foo()!");
}
console.log(typeof foo); // string
foo
의 타입을 확인하면 string
이다. 즉, 변수 할당이 우선한다.
변수 할당과 함수 선언의 위치를 변경해도 결과는 동일하다.
function foo() {
console.log("I'm foo()!");
}
var foo = "Hello World";
console.log(typeof foo); // string
var foo;
function foo() {
console.log("I'm foo()!");
}
console.log(typeof foo); // function
foo
의 타입을 확인하면 function
이다. 즉, 함수 선언이 변수 선언보다 우선한다.
함수 선언과 변수 선언의 위치를 변경해도 결과는 동일하다.
function foo() {
console.log("I'm foo()!");
}
var foo;
console.log(typeof foo); // function
Hoisting
한다.Hoisting
되지 않는다.