자바스크립트가 가지고 있는 특성
자바스크립트 Parser가 함수 실행 전에 해당 함수를 한 번 쭉 훑으면서 함수 안에 존재하는 변수들을 해당 스코프의 최상단으로 hoist(끌어올리기) 하는 것
호이스팅의 대표적인 예시
var
로 선언한 변수, 함수선언문의 경우에 Hoisting이 발생한다.
var
로 선언한 변수의 호이스팅console.log(a); // undefined
var a = 1;
console.log(a); // 1
호이스팅 시 변수의 선언 & undefined
로 초기화가 함께 이루어진다
값 할당은 나중 가서 하더라도, 코드 어디든 변수 선언문이 있으면 에러가 발생하지 않음.
위의 코드가 이렇게 동작한다고 이해하면 된다!
var a;
// 일단 변수 선언 부분을 끌어올린 다음, 변수선언문을 만나기 전이므로 undefined로 초기화한다.
console.log(a); // undefined
a = 1; // 값 할당은 원래 순서에서 일어난다.
console.log(a); // 1
equal(1, '1'); // 아무 문제 없이 결과값을 반환한다 'false'
function equal(value1, value2) {
return value1 === value2;
}
함수선언문의 작성 위치와 관계없이 맨 위로 호이스팅되기 때문에 문제없이 작동한다.
다만 변수에 함수를 할당하는 경우(함수표현식) 호이스팅이 일어나지 않는다.
equal(1, '1); // TypeError: equal is not a function
var equal = function(value1, value2) {
return value1 === value2;
};
var equal
부분만 호이스팅되기 때문이다.
const
, let
으로 선언한 변수도 호이스팅이 일어난다.
다만 변수 생성 방식이 달라 var
의 호이스팅과는 차이가 존재한다.
변수의 생성 단계는 다음과 같다.
: 선언 단계
> 초기화 단계
(메모리 공간 확보) > 할당 단계
var
- 스코프의 선두에서 선언과 초기화가 한 번에 이뤄진다. 선언문을 만나지 않았더라도 일단 undefined로 초기화를 진행한다.
let
, const
- 스코프의 선두에서 선언 단계만 실행된다. 선언문을 만나야 초기화 단계가 실행된다. 즉, 선언문 전에 변수를 참조할 수 없다.
(이때 선언 단계와 초기화 단계 사이를 변수의 TDZ라고 부르기도 한다. Temporal Death Zone의 약자로, 이 영역 안의 변수들은 접근할 수 없게 되어 있음 ⇒ ReferenceError
가 발생)
할당문을 만나야 할당 단계가 이뤄진다는 점은 동일하다.
console.log(a); // undefined
// a의 선언과 undefined로의 초기화가 이뤄진 상태
var a;
console.log(a); // undefined
a = 1;
console.log(a); // 1
console.log(b); // ReferenceError가 발생한다.
let b;
// 변수 선언문을 만났을 때 초기화 단계가 실행된다.
console.log(b); // undefined
b = 2;
console.log(b); // 2
결론적으로, 이 차이 때문에 let
으로 선언된 변수의 경우 호이스팅으로 인해 발생하는 대표적인 특성(선언 전 참조 가능)을 가지지 않는다. 그래서 let
은 호이스팅이 발생하지 않는다는 설명이 돌아다니는 것 같기도.
(const
의 경우 애초에 값의 선언부터 할당까지 한 번에 이루어져야 하기 때문에 호이스팅에 대해 다룰 때는 논외로 여겨지는 듯하다.)
References
자바스크립트 컨텍스트 바인딩 (this)
this | PoiemaWeb