호이스팅이란, 메모리에 미리 할당하는 것을 의미한다.
자바스크립트에서는 호이스팅이라는 개념이 있지만 호이시팅을 지양하는 분위기다. 호이스팅은 예측하지 못할 결과를 초래할 가능성이 존재하기 때문이다.
호이스팅이 적용되는 경우는 var
를 사용하거나 함수 선언을 하는 경우다.
먼저 예측하지 못할 가능성에 대한 예제를 몇가지만 만들어 보려고 한다.
console.log(myVariable); // undefined
var myVariable = 33;
console.log(myVariable); // 33
var
를 사용하게 되면 호이스팅이 되어 위 코드에 선행되어 myVariable
의 선언이 먼저 이루어진다. 다음과 같은 코드로 호이스팅을 표현할 수 있겠다.
var myVariable; // 선언
console.log(myVariable); // undefined
myVariable = 33; // 할당
console.log(myVariable); // 3당
이렇게 호이스팅이 되면 myVariable
이 원래 목적한 값이 아닌 undefined
으로 사용될 수 있으며 에러도 발생하지 않으므로 예기치 못한 동작을 발생할 수 있음.
var 대신 let, const 사용하기
let
, const
는 호이스팅을 적용되지 않으며 앞서 코드에서 var
를 let
으로만 바꾸어도 에러가 발생하는 것을 알 수 있음.
ReferenceError: Cannot access 'myVariable' before initialization
함수의 호이스팅
var
와 마찬가지로 함수 역시 호이스팅이 적용된다. 호이스팅되는 동작에 대한 예를 암기한다기 보다는 var
의 경우처럼 호이스팅이 되는 경우에 예측하기 힘든 동작이 발생할 수 있다는 점만 이해하는 것이 중요하다.
다음의 경우 예측하기 힘든 동작을 보여준다.
console.log(sum); // Function: sum
var sum =33;
function sum(a, b) {
return a + b;
}
var
선언된 sum
과 함수 sum
은 모두 호이스팅되었다. 선언된 순서대로 덮어쓰게 되므로 찍히는 로그는 함수가 맞다. 이제 아래 로그를 찍는 동일한 한줄의 코드(console.log(sum)
)를 추가해 보자.
console.log(sum); // Function: sum
var sum =33;
function sum(a, b) {
return a + b;
}
console.log(sum); // 33
동일한 sum을 찍지만 아래는 33
이 찍힌다. 이유는 sum
에 33
이 할당되는 코드가 두 console.log(sum)
사이에 있어 sum의 값이 변경되어서다.
이렇게 예측하기 힘든 코드는 사용하면 안된다.
함수 호이스팅을 막는 방법
함수 표현식을 사용하면 호이스팅을 막을 수 있다.
console.log(sum);
// 함수 표현식
const sum = function sum(a, b) {
return a + b;
}
//// ReferenceError: Cannot access 'sum' before initialization
함수 표현식은 호이스팅이 안되므로 함수선언문에서는 가능했던 코드지만 함수표현식을 사용하면 위와같이 에러가 발생한다.