호이스팅이란?
코드 실행 전, 변수/함수선언이 파일의 맨 위로 끌어 올려진 "것 같은 현상"을 이야기한다.
Hoisting이 발생하는 이유
자바스크립트 엔진 동작의 특징 때문!
- 코드를 실행하기 전 실행 가능한 코드를 형상화하고 구분하는 과정을 거침 (실행 컨텍스트를 위한 과정)
- 코드를 실행하기 전 실행 컨텍스트를 위한 과정에서 모든 선언들(var, let, const, function, class)을 메모리에 저장.
- 코드 실행 전 이미 변수/함수 선언이 메모리에 저장되어 있기 때문에 선언문보다 참조/호출이 먼저 나와도 오류 없이 동작.
(정확히는 var 키워드로 선언한 변수와 함수 선언문일 경우 오류 없이 동작.) - 따라서 이는 선언이 파일의 맨 위로 끌어올려진 것 처럼 보이게 한다.
*실행 컨텍스트는 실행 가능한 코드가 실행되기 위해 필요한 환경을 의미하고 실행되기전 이러한 실행 컨텍스트 과정(코드를 구분하는 과정)을 거침.
Hoisting의 특징
- 자바스크립트의 모든 선언에는 호이스팅이 일어남.
- let,const,class를 이용한 선언문은 호이스팅이 발생하지 않는 것 처럼 동작한다.
(선언 전에 호출하면 ReferenceError발생) - 이 같은 현상이 발생하는 이유는 스코프의 시작에서 변수의 선언까지 “일시적 사각지대”에 빠지기 때문.
- var은 선언과 함께 undefined로 초기화 되어 메모리에 저장되지만, let, const는 초기화 되지 않은 상태로 메모리에 올라가기 때문에 참조에러 발생.
let num = 9;
{//Block Scope
console.log(num);
let num = 2;
}
[예시] 위 예시에서 선언이 hoisting되었으므로 block scope에서 num을 찾을 수 없음.
변수생성과정
1단계) 선언 단계 (Declaration Phase)
- 변수를 실행 컨텍스트의 변수 객체에 등록.
- 이 변수 객체는 스코프가 참조하는 대상이 됨.
2단계) 초기화 단계(Initialization phase)
- 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보.
- 이 단계에서 변수는 undefined로 초기화 됨.
3단계) 할당 단계 (Assignment phase)
- undefined로 초기화된 변수에 실제 값을 할당.
- var 키워드로 선언한 변수는 선언 단계와 초기화 단계가 한번에 이루어짐.
- let키워드로 선언된 변수는 선언단계와 초기화 단계가 분리되어 실행된다.
- let, const의 경우 초기화는 코드 실행 후, 변수 선언문에 도달했을 때 이루어짐.따라서 초기화 이전에 변수 접근시 변수를 위한 메모리 공간이 확보되지 않았기 때문에 에러발생.
- 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 ‘일시적 사각지대(Temporal Dead Zone; TDZ)라고 부름.
Hoisting 테스트를 위한 몇가지 실습
1)
console.log(name);
//선언된 변수도 없고 할당된 메모리 공간도 없으므로
//ReferenceError 발생
console.log(name);
name = "Jook";
//위 예제와 동일하게 선언이 되지 않았으므로
//ReferenceError 발생
console.log(name);
name="Jook";
var name;
//var 키워드로 name을 선언하였으므로 에러발생은 안함.
//undefined 출력
console.log(name);
//Jook 출력
2)
console.log(name);
let name;
//name 변수 선언은 되었지만 초기화 되지 않음.
//ReferenceError 발생.
let name;
console.log(name);
//name 변수 선언
//선언부에서 name을 undefined 초기화.
//undefined 출력.
3)
//Func1은 함수 선언문으로 Hoisting되어 정상 실행
console.log(Func1);//[Function: Func1]
//Func2은 함수 표현식으로 변수 선언,초기화까지만 진행된 상태.
console.log(Func2);//undefind
Func1();//Func1 출력
Func2();//Func2 is not a function 출력.
function Func1(){
console.log("Func1");
}
var Func2 = function(){
console.log("Func2");
}
[참고 https://hanamon.kr/javascript-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85%EC%9D%B4%EB%9E%80-hoisting/]
'Language > Javascript' 카테고리의 다른 글
[Javascript] Promise의 기본 (1) | 2022.10.04 |
---|---|
[Javascript] ES6 Array helper (0) | 2021.11.19 |
[Javascript] 싱글스레드 기반 이벤트 루프와 비동기 (0) | 2021.11.18 |
[Javascript] Scope와 변수 선언 (var, let, const) 키워드 차이점 (0) | 2021.11.12 |
[Javascript] ES6 문법 정리 (0) | 2021.11.10 |