1) 호이스팅이란?
(1) 호이스팅 개념
- 변수&함수 선언만 해당 스코프의 최상단으로 끌어올려지는 걸 호이스팅이라고 한다.
- 아래와 같이 변수를 선언해도 상단에서 변수 참조가 가능하다.
console.log(a)
var a;
- 단, 변수의 선언만 끌어올려지므로 값을 할당해도 결과는 undefined가 된다.
console.log(a)
var a = 1;
2) 호이스팅이 발생하는 이유
(1) 왜 발생할까?
🏃🏻 자바스크립트 엔진에서 변수를 생성하는 단계를 먼저 살펴보자
- 자바스크립트 엔진에서 변수는 선언 → 초기화 → 할당을 거쳐 생성된다.
단계설명
선언 단계 | 변수를 실행 컨텍스트(실행 코드에 제공할 정보 객체)의 변수 객체에 등록한다. |
초기화 단계 | 변수 객체에 등록된 변수를 위한 메모리 공간을 확보한다. (이때, undefined로 초기화됨) 메모리가 할당되면 메모리 참조를 통해 변수에 접근할 수 있다. |
할당 단계 | 사용자가 정의한 값을 변수에 할당해준다. |
- 자바 스크립트 엔진은 코드를 실행하기 전에 실행 컨텍스트에 등록된 변수 객체에 접근할 수 있다.
- var의 경우 변수 선언&초기화가 함께 진행되므로, 변수 객체 등록과 동시에 메모리 공간도 할당 받는다.
- 그렇기 때문에 메모리를 할당받은 상태이므로 호이스팅시 메모리 참조를 통해 변수 접근이 가능하다.
console.log(a); // 변수 접근 가능
var a; // 실행 컨텍스트에 등록 & 메모리 할당 받음
- let의 경우, 선언과 초기화를 각각 진행한다.
- 선언 단계에서 실행 컨텍스트에 등록은 했지만, 메모리를 할당받지 못해 접근이 불가능한 상태이다.
- 결국, 메모리를 할당받지 못해 참조할 메모리가 없으므로 ReferenceError가 발생한다.
console.log(a); // 변수 접근 불가능
let a; // 실행 컨텍스트에 등록 & 메모리 할당 못 받음
- 함수 선언문의 경우, 선언 & 초기화 & 할당이 동시에 진행되므로 호이스팅은 물론 실행도 가능하다.
print() // a
function print() {
console.log('a')
}
- 단, 아래와 같이 함수표현식을 사용한다면 호이스팅이 불가하다.
print() // error
const print = () => {
console.log('a')
}
3) let, const는 호이스팅이 불가하다?
🏃🏻 let, const는 왜 ReferenceError가 발생할까? TDZ와 함께 알아보자.
- TDZ(Temporal Dead Zone)는 선언 ~ 초기화 단계 사이를 이야기한다.
- 아래와 같이 선언보다 먼저 호출하면 ReferenceError가 발생하는데, 이를 TDZ에 걸렸다고 얘기한다.
console.log(a)
// error: Uncaught ReferenceError: Cannot access 'a' before initialization
let a = 12;
const 선언방식을 예로 보자. 우리가 예상했던 대로 ReferenceError가 발생한다.
console.log(a); // ReferenceError
const a = '1';
- const a = '1' 전까지, 변수 a 는 TDZ 구간에 놓여 있다.
- 그 이유는 var과 달리 const는 코드를 실행하는 시점에서는 실행 컨텍스트 추가만 됐기 때문이다.
- 그러므로 console.log(a) 입장에서는 변수 a는 선언~초기화 사이 단계인 것이며, 이 때는 메모리 할당을 받지 못해 참조할 메모리가 없으므로 ReferenceError: Cannot access 'a' before initialization 자바스크립트 에러가 발생한다.
🏃🏻 단, 참조할 메모리가 없는 것이지 호이스팅이 발생하지 않는 건 아니다.
'프론트 > javascript' 카테고리의 다른 글
javascript eventListener 방법 메모 (0) | 2022.08.30 |
---|---|
ES6 자바스크립트 최신 문법 (0) | 2022.08.05 |
Todo App 만들기 (0) | 2022.08.03 |
숫자 예상 게임과, GitHub와 Netlify를 이용한 쉽고 빠른 HTTPS 무료 호스팅 (0) | 2022.08.03 |
var, let, const (0) | 2022.07.13 |