[JS] 호이스팅(Hoisting) 은 무엇?
호이스팅(Hoisting) 개념
★ var / let, const 변수 함수선언문 함수표현식 등 모두 끌어올려 우선순위로 최상단에 선언하는 것
Hoist(:끌어 올리다) + -ing 을 이어 붙인게 호이스팅이란 표현이다.
호이스팅(Hoisting) Rule
호이스팅은 함수 호이스팅과 변수 호이스팅으로 나뉜다.
- 선언된 함수는 상단에서 참조, 호출이 가능하다.
- 선언된 var 는 상단에서 참조, 할당이 가능하다.
- 선언된 let, const 는 상단에서 참조, 할당이 불가능하다.
함수 호이스팅(Function Hoisting)
함수 호이스팅은 호이스팅중에 가장 먼저 이루어진다. 하지만 여기서 헷갈리는 사람들이 있는데,
함수 선언문과 함수 표현식은 다른 것이다.
ex) 코드 예제
// 함수 선언문
function sum(a, b) {
console.log(a + b)
}
// 함수 표현식
const sum = (a, b) => {
console.log(a + b)
}
함수 선언문은 호이스팅할 때 최우선적으로 처리되지만, 함수 표현식은 var, let, const에 할당하는 방식으로 변수 선언문과 크게 다를게 없다.
변수 호이스팅(Variable Hoisting)
변수 호이스팅은 세가지 단계를 거친다. 또한 var와 let, const 는 호이스팅이 조금 다르게 적용된다.
- 선언: 파싱 과정에서 변수 객체가 변수에 대한 식별자들을 수집한다.
- 초기화: 식별자에 메로리를 할당하고 undefine 상태를 부여한다.
- 할당: 변수 안에 직접 값을 넘겨 준다.
변수 호이스팅은 함수 호이스팅과 마찬가지로 선언과 초기화를 해주어야 값의 참조 및 할당이 가능하다.
단 위에 설명한 것 처럼 var 인지 let, const인지에 따라 선언, 초기화 시점이 달라진다.
console.log(a)
let a = 1
이 코드를 실행시키면 ReferenceError: a is a not define 이란 에러가 발생한다.
let 과 const는 동작하는 과정에서 스코프의 진입지점과 해당 식별자의 실질적 선언부 사이를 이렇게 부른다.
일시적 사각지대 (Temporal Dead Zone)라고 한다. 변수는 존재 하지만, 초기화가 되어있지 않다.
하지만 그렇다고 let 과 const가 호이스팅 대상이 아닌것은 아니다. 호이스팅은 인접 스코프 상단에서 선언부를 관측할 수 있는 현상이기에 let 과 const 또한 호이스팅 대상이라고 보는 게 맞다.
또한 변수 호이스팅은 엄격히 지양되고 있다. var 호이스팅에 몇가지 문제가 존재하기 때문이다.
- 블록 레벨 스코프가 아닌 함수 레벨 스코프에 정의된다.
- 변수를 중복으로 불러 덮어씌울 수 있게 한다.
- 호이스팅으로 인해 선언 전에도 변수를 참조할 수 있게 된다.
위 문제로 인해 자신의 의도와 다르게 스코프에서 변수를 덮어씌워서 문제가 발생할 수있다. 이러한 경우 에러를 찾기도 쉽지가 않아 곤혹을 겪는다. 때문에 협업을 할 때에는 var를 사용하는것은 자제하는 것이 좋다. 때문에 var 의 유연성 때문에 발생하는 피해를 방지하기 위해 let 과 const 를 사용하여 이슈를 방지하는게 좋다.
결론
호이스팅은 실제로 많은 이슈와 버그를 일으키는 녀석이다.. 많은 사람들이 Hoisting 동작을 이해하고 사용 했으면 좋겠다!