[JS] 호이스팅(Hoisting)을 이해해보자!
[JS] 호이스팅(Hoisting)을 이해해보자!
1. 호이스팅이란?
호이스팅
은 어원 그대로 변수나 함수의 선언이 코드 최상단으로 끌어올려지는 듯한 현상을 말한다.
var name = 'global name';
function callName() {
console.log(name); // ?
var name = 'local name';
};
callName();
위 예제 코드에서 출력되는 변수 name
의 값은 'global name'
일 것 같지만, undefined
이다.
특정 스코프 안에서 선언된 변수(name)는 코드에 적힌 순서와 상관없이 "최상단에서 선언한 것처럼" 끌어올려진다. 이것을 호이스팅이라고 한다.
var name = 'global name';
function callName() {
var name;
console.log(name); // undefined
name = 'local name';
};
callName();
사실 위 예제 코드의 순서처럼 진행된다. 이를 제대로 이해하기 위해서는 TDZ
와 변수의 생성 단계
에 대한 이해가 필요하다.
2. 변수의 생성 단계
자바스크립트에서 변수(variable)는 3가지 단계를 걸쳐 생성된다. 이 과정은 실행 컨텍스트 포스팅 참고하면 도움이 된다.
Step 1. Declaration phase : 선언 단계
- 변수를 실행 컨텍스트의
변수 객체
에 등록하는 단계이다. - 이 변수 객체는 스코프가 참고하는 대상이 된다.
Step 2. Initialization phase : 초기화 단계
- 실행 컨텍스트에 존재하는
변수 객체
에 선언 단계에서 생성된 변수를 위한 메모리를 만드는 단계이다. - 이 단계에서 할당된 메모리에
undefined
를 할당한다.
Step 3. Assignment phase : 할당 단계
- 초기화 단계에서 undefined로 초기화된 메모리에 다른 값을 할당하는 단계이다.
3. var과 let의 변수 생성 과정
1. var 키워드 변수
var 키워드 변수는 선언 단계
와 초기화 단계
가 동시에 진행된다. 즉, 자바스크립트 내부적으로 실행 콘텍스트의
변수 객채에 변수를 등록하는 동시에 메모리를 undefined로 만들어버린다.
그렇기 때문에 변수에 값이 할당되기 전에 호출해도 Reference 에러가 발생하지 않고, undefined가 리턴된다.
2. let 키워드 변수
let 키워드는 var 키워드와 다르게 선언 단계와 초기화 단계가 분리되어 진행된다. 실행 컨텍스트의 변수 객체에 변수를 등록했지만, 메모리에 할당되지 않아 접근할 수 없다. 그래서 Reference Error: Cannot access before initialization
에러 문구가 나오는 것이다.
즉, 호이스팅 되지 않는 것이 아니라, 호이스팅은 되었으나 메모리가 할당되지 않아 접근할 수 없는 것이다. 이때 등장하는 개념이 TDZ 이다.
💀 TDZ 란?
한글로 직역하자면 일시적인 사각지대이다.
스코프 시작 지점 에서 초기화 시작 지점 까지를 TDZ(Temporal Dead Zone) 라고 한다.
3. function 키워드 함수
함수 표현식의 경우, 선언/초기화/할당 단계가 모두 동시에 진행된다. 그래서 할당 전 호출해도 undefined가 아니라, 함수 내용이 리턴된다.
4. 총 정리
- 자바스크립트 엔진은 코드를 실행하기 전, 실행 가능한 코드를 형상화하고 구분하는 과정(⇒ 실행 컨텍스트 형성)을 거친다.
- 이 과정에서 모든 선언(var, let, const, function, class)이 변수 객체 메모리에 저장된다.
- 코드 실행 전 이미 변수, 함수에 대한 선언이 저장되어 있기 때문에, 선언문보다 참조 및 호출이 먼저 나와도 동작할 수 있게 된다.
- 이는 선언 구문이 마치 파일의 최상단으로 끌어올려진 것처럼(호이스팅 된 것처럼) 보인다.
참고
'프로그래밍 > JAVASCRIPT 사전' 카테고리의 다른 글
[JS] 객체에 조건부 프로퍼티 적용하기 (0) | 2022.06.05 |
---|---|
[JS] 모듈 import/export 문법 빠르게 정리하기 (0) | 2021.09.18 |
[JS] scope 와 실행 컨텍스트 (0) | 2021.06.11 |
[JS] this란? 모든 케이스를 정리해보자 (0) | 2021.06.08 |
[JS] 화살표 함수, 쉽고 빠르게 정리하기 (8) | 2021.05.11 |
댓글
이 글 공유하기
다른 글
-
[JS] 객체에 조건부 프로퍼티 적용하기
[JS] 객체에 조건부 프로퍼티 적용하기
2022.06.05 -
[JS] 모듈 import/export 문법 빠르게 정리하기
[JS] 모듈 import/export 문법 빠르게 정리하기
2021.09.18 -
[JS] scope 와 실행 컨텍스트
[JS] scope 와 실행 컨텍스트
2021.06.11 -
[JS] this란? 모든 케이스를 정리해보자
[JS] this란? 모든 케이스를 정리해보자
2021.06.08