늘 겸손하게

JavaScript - Hoisting ( 호이스팅 ) 본문

Programming/JavaScript

JavaScript - Hoisting ( 호이스팅 )

besforyou999 2022. 8. 12. 14:00

호이스팅에 대해 알아보자

 

console.log(student);

var student = "Mike";

console.log(student);

 

위 코드를 실행시킬 수 있을까?

 

정답은 "Yes"

 

위 코드를 브라우저에 로드해보았다. 

 

 

첫 번째 console.log에서 undefined가 출력되지만 오류가 생기진 않은다.

 

이처럼 선언문이 마치 최상단에 끌어올려진 듯한 현상을 hoisting(호이스팅)이라고 부른다.

 

 

 

Hoisting (호이스팅) 정의

 

 

-> 선언문이 마치 최상단에 끌어올려져 선언문 이전의 변수값이 참조가 가능한 현상

 

 

 

호이스팅이 발생하는 이유

 

 

호이스팅 발생 이유를 알기 위해선 자바스크립트 엔진이 코드를 실행하는 과정을 알아야한다.

 

- 자바스크립트 엔진이 코드를 실행하는 순서

 

1. Global Execution Context를 Call Stack에 담는다.

 

2. 함수가 선언되면 해당 함수의 Execution Context를 Call Stack에 쌓는다.

 

3. stack 맨 위의 context가 활성화된 Execution Context

 

4. stack 맨 위부터 아래로 내려가며 Execution Context 실행

 

5. 코드 실행이 종료되면 Global Execution Context stack에서 제거

 

(위 예시코드에서는 함수가 없으므로 Global Execution Context만 Call Stack에 존재한다.)

 

 

실행 컨텍스트(Execution Context)란 식별자 결정를 빠르고 효율적으로 하기 위해 필요한 정보를 한데로 모은 객체로 Environment Record와 Outer를 포함한다.

 

실행 컨텍스트 간략한 묘사

여기서 Environment Record, 즉 Record에 변수명이 기록된다.

 

 

자바스크립트 엔진은 코드를 실행할 때 생성 단계(Creation Phase)실행 단계(Execution Phase)를 거친다.

 

생성 단계 (Creation Phase)에서 자바스크립트 엔진은 Execution Context를 생성하고 선언문만 실행해서 Environment Record에 식별자(함수명, 변수명)를 기록한다.

 

변수를 var로 선언한 경우 자바스크립트 엔진은 Environment Record에 변수를 기록하고 undefined를 바인딩합니다.

변수를 const, let으로 선언한 경우 자바스크립트 엔진은 Environment Record에 변수를 기록하지만 값을 바인딩하지는 않습니다.

 

그 후 실행 단계(Exection Phase)에서 선언문 외 나머지 코드를 실행합니다. 이때 Environment Record를 참조하거나 업데이트합니다.

 

그러므로 위 예제 코드에서 첫 번째 줄에 undefined가 출력된 이유는 생성 단계에서 'student' 변수명이 Environment Record에 기록되고 var로 선언했으므로 생성 단계에서 undefined값이 바인딩됩니다. 그 후 실행 단계에서 코드가 실행되면서 undefined가 바인딩된 변수 student를 참조해서 console.log가 undefined를 출력하는것입니다.

 

 

 

호이스팅이 발생하는 이유

 

 

자바스크립트 엔진의 코드 실행 과정은 생성 단계 -> 실행 단계를 거치는데 생성 단계에서 변수명, 함수명이 Execution Context의 Record에 기록되고 실행 단계에서 Record에 기록된 값을 참조하기 때문에 선언문 이전의 변수값도 참조가 되는것.