Javacript 특징으로 Hoisting에 대해서 설명한다.
이러한 특징들을 알고 있어야 개발 효율성이 높아지고 적절한 개발을 진행 할 수 있다.
변수 선언이 함수 또는 전역 코드의 상단에 이동하는 것과 같은 행동을 "호이스팅(hoisting)"이라고 한다. 즉, 자바스크립트는 모든 선언문(var, let, const, function, function*, class)이 선언되기 이전에 참조 가능하다.
호이스팅을 변수 및 함수 선언이 물리적으로 작성한 코드의 상단으로 옮겨지는 것으로 인식되지만, 실제로는 그렇지 않다. 변수 및 함수 선언은 컴파일 단계에서 메모리에 저장되지만, 변수 및 함수는 코드에서 입력한 위치와 정확히 일치한 곳에 존재한다.
js 인터프린터가 자바스크립트 코드를 해석함에 있어서 Global 영역의 선언된 코드블럭을 최상의 Scope로 끌어올리는 것을 hoisting이라고 붙여서 언어적 특징이 되었다.
개발에 적극적으로 사용한다던지 그런것 보다는 개발을 할 때 언어적 특성을 고려하여 프로그래밍을 해야만 효율적인 결과물을 만들 수 있기 때문에 알고 있어야만 한다.
ES6 이전에는 var
를 통해 변수를 선언하였다. function scope를 가지기 때문에 최상단으로 hositing된다.
console.log(x);
var x = 10;
console.log(x);
// 결과
// undefined
// 10
위와 같이 변수를 선언하지 않고 출력을 하지만 오류 없이 undefined라고 하고 넘어간다.
var x = 10
이 구문에서 var x
를 호이스트하기 때문이다.
호이스트된 실제 동작을 풀어서 쓰면,
var x; // Hoisting
console.log(x);
x = 10;
console.log(x);
// 결과
// undefined
// 10
ES6에서는 var
를 사용하지 않고 let
과 const
를 사용한다.
var
키워드로 선언된 변수와는 달리 let
키워드로 선언된 변수를 선언문 이전에 참조하면 참조 에러(ReferenceError)가 발생한다. 이는 let
키워드로 선언된 변수는 스코프의 시작에서 변수의 선언까지 일시적 사각지대(Temporal Dead Zone; TDZ)에 빠지기 때문이다.
// 스코프의 선두에서 선언 단계가 실행된다.
// 아직 변수가 초기화(메모리 공간 확보와 undefined로 초기화)되지 않았다.
// 따라서 변수 선언문 이전에 변수를 참조할 수 없다.
console.log(foo); // ReferenceError: foo is not defined
let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined
foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1
let
과 const
는 block scope를 가지기 때문에 아래와 같은 reference 에러가 발생한다.
let foo = 1; // 전역 변수
{
console.log(foo); // ReferenceError: foo is not defined
let foo = 2; // 지역 변수
}
함수도 변수 Hoisting과 마찬가지로 Hoist되서 실행된다. 여기서 주의할 점은 함수 Hoisting은 함수를 Hoist하지만 변수의 값은 끌어올리지 않는다.
say();
function say(){
console.log("hello");
}
// 결과
// hello
위와 같이 say() 함수 선언부가 hoisting 되면서 오류 없이 실행되었다.
아래와 같이 변수에 함수 리터럴을 할당해 놓으면 hoisting이 되지 않으면서 오류가 발생한다.
say();
var say = function(){
console.log("hello");
}
// 결과
// syntax error
변수 hoisting이 함수 hoisting보다 먼저 일어난다.
너무 많은 선언문이 남발되어 있는 자바스크립트 코드는 실행코드의 해석시점이 뒤로 밀리게 됨으로서 자바스크립트 실행코드의 구동시점이 길어지는 좋지않는 결과를 가져오기도 한다.
글로벌함수,변수를 너무 많이 정의해놓으면 hoisting에 의해 지연이 발생할 수 있다.