호이스팅
8/9/2022
작성자 : 홍원배
식별자의 선언문이 스코프의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징으로 선언문 코드 이전에 변수나 함수를 참조하거나 함수를 호출할 수 있게 만든다
JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다 - MDN
- 모든 선언문은 런타임 이전(소스코드의 평가)에 실행되기 때문에 발생하는 특징이다
- 변수 var는 런타임 이전에 초기화까지 이뤄지기 때문에 참조 가능하지만 let과 const는 TDZ에 빠져 초기화가 런타임 이후에 이뤄짐
- 함수의 선언은 초기화까지 이뤄지는 정의라고 할 수 있다
- 정의 : 어떤 대상을 명확하게 규정
선언 vs 정의 ⇒ 자바스크립트에서는 구분이 모호하다
다른 프로그래밍 언어에서는 선언과 정의를 엄격하게 구분한다. 예를 들어 c언어에서 선언과 정의는 ‘실제로 메모리 주소를 할당한가’로 구분한다. 단순히 컴파일러에게 식별자의 존재를 알리는 것이 선언, 실제로 컴파일러가 변수를 생성해서 식별자와 메모리 주소가 연결되면 정의로 구분한다. 자바스크립트의 경우 변수를 선언하면 암묵적으로 정의가 이뤄지기 때문에 선언과 정의의 구분이 모호하다
var키워드로 선언된 변수는 undefiend로 초기화되고, 함수 선언문을 통해 암묵적으로 생성된 식별자는 함수 객체로 초기화된다
- 선언이 없는
name = ‘hong’
과 같은 코드는 호이스팅이 일어나지 않는다
- 선언이 없었음에도 참조하여 코드를 작성하면 코드의 복잡성을 증가시키기 때문에 지양
let, const의 호이스팅
변수, 함수, 클래스 등의 식별자의 선언문은 모두 호이스팅 되지만 let, const는 호이스팅이 일어나지 않은 것 처럼 보인다
하지만 일시적 사각지대(TDZ) 에 있을 뿐, 호이스팅이 일어나지 않은 것은 아니다
변수의 생명주기는 선언 - 초기화 - 할당
변수의 선언은 런타임 이전 (소스코드의 평가)에 실행 컨텍스트에 등록되며 변수의 초기화와 할당은 런타임 이후(소스코드의 실행)에서 이루어진다. 하지만 var 키워드는 선언과 초기화가 런타임 이전에 함께 실행된다
결국, let, const와 var의 차이는 초기화가 언제 일어나냐에 있다
함수의 호이스팅
함수 선언문으로 정의한 함수가 평가되면 함수 이름과 동일한 이름의 식별자를 객체 환경 레코드에 바인딩된 BindingObject를 통해 전역 객체에 키로 등록하고 생성된 함수 객체를 즉시 할당한다. 이것이 변수 호이스팅과 함수 호이스팅의 차이
⇒ 함수 선언문은 런타임 이전에 참조할 수 있지만 변수는 키워드에 따라 언제 참조하는지가 다르기 때문에 차이가 발생한다
- 함수는 선언과 동시에 할당이 이뤄지기 때문에 (객체로 유동적으로 메모리 공간 차지) 참조할 수 있다.
- 함수가 함수표현식으로 나타내졌을 때는 변수 선언문의 영향을 받는다
- 함수가 선언문으로 정의 되었을 때는 함수 호이스팅을 따르고 함수 표현식이었을때는 변수 호이스팅을 따른다
클래스의 호이스팅
- let, const와 동일하게 TDZ에 영향을 받는다
- 호이스팅이 일어나지만 일어나지 않은 것처럼 동작한다