본문 바로가기

정보/프로그래밍 언어

JavaScript 엔진 동작 원리와 Hoisting

JavaScript는 함수형 프로그래밍을 베이스로 한 언어이다.

 

따라서 .js파일을 실행한다는 것은 해당하는 함수와 파라미터,

다시 말해 변수(JS에서는 함수 또한 변수)에 대한 메모리를 할당하고,

이 함수들을 실행한다는 것을 말한다.

 

이 일련의 과정들이 어떻게 진행되는지 간단하게 정리하면 다음과 같다.

 

1. Execution Context (E.C) 생성

  • 엔진이 코드를 실행할 때, 제일 먼저 생성하는 것
  • 글로벌 코드에서 생성되거나 함수 호출 시 마다 별도로 생성 됨.
  • Call Stack으로 관리된다. 함수가 호출될 때 마다 새로운 E.C가 글로벌 context위에 쌓이는 형식
  • 크게 3가지의 종류가 있다.
    • Global Context : 프로그램이 실행되면 가장 먼저 실행. 모든 전역 변수, 함수 관리
      • JS에서 사용되는 main 과 같은 Global function에 대한 context라고 생각하면 된다.
        Node.js에서 사용되는 웹 서버에서는 global이라는 global object를,
        웹 브라우저에서는 window라는 global object를 갖는다.
    • Local Context : 특정 함수가 호출 될 때마다 생성. 이 안에서 지역 변수 등을 관리
    • (Eval Context) : eval 함수에 대해서 따로 구분하는 형식인데, eval 사용은 위험해서 사실상 안씀
  • Variable Environment + Lexical Environment ( + This Binding) 으로 구성되어 있다.
    • Variable Environment : var, let, const로 선언된 변수들이 이 환경에서 관리됨
    • Lexical Environment : 변수의 선언 위치를 기준으로 변수에 접근하는 규칙을 정의
      • 변수를 실제로 기록, 저장하는 공간(let, const로 선언된 변수들만)과
        상위 스코프(부모 스코프)에 대한 참조를 적는 공간이 있다. 
    • This Binding : this가 가리키는 것에 대한 정보

 

2. Creation Phase

  • 변수와 함수 선언을 위한 메모리 공간 확보
  • var, let, const로 선언된 변수들을 메모리에 등록한다.
  • 함수 선언
  • lexical Scope 저장 : 함수가 선언된 시점의 렉시컬 환경을 저장.
    함수 내부에서 참조할 변수를 선언 시점 기준으로 바인딩.

 

2 - 1. 변수의 메모리 할당 과정

  • 선언 : 해당 변수를 메모리에 등록만 하는 과정이다. 값이 초기화 되지는 않은 상태
  • 초기화 : 변수에 어떤 값을 처음으로 설정 하는 것.
  • 할당 : 변수에 값을 넣는 모든 행위 (초기화 포함)
  • 재할당 : 이미 할당된 값을 다시 변경하는 행위.

 

이미지 출처 : https://www.youtube.com/watch?app=desktop&v=EvfRXyKa_GI

2 - 2. Hoisting

  • Creation Phase에서 엔진은 코드 내의 모든 선언된 변수와 함수를 메모리에 등록한다.
  • var와 같은 경우, 이를 통해 변수가 선언되기도 전에 사용할 수 있는 경우가 존재함
  • 함수도 마찬가지
  • 이와 같은 현상을 Hoisting이라고 한다. 
  • 변수 선언이 함수 또는 전역 코드 상단에 이동하는 것과 같은 현상
console.log(bla)	// undefined
bla = 2; 		// 선언 전(메모리 등록 전)에 할당이 가능한 것처럼 보임
var bla;

varHoisting()		// This is Hoisting
function varHoisting() {
	console.log("This is Hoisting.")
}
  • let, const도 Creation Phase에서 Hoisting이 일어나기는 한다. 다만 이때 초기화가 이뤄지지 않음.
    선언된 코드 라인에 와서야 값이 초기화 되고, 할당이 가능해지기에 var와 같은 사용은 불가능
    • let, const 선언 이전의 초기화 및 값 할당이 불가능한 지역을 TDZ(Temporal Dead Zone)
  • var 는 Creation Phase에서 선언과 동시에 undefined로 초기화 되기에 값의 할당이 가능하다.

 

3. Execution Phase

  • 변수에 값을 할당한다.
    • let, const는 초기화
    • var는 이미 undefined로 초기화가 이루어졌기에 코드에 삽입한 값으로 재할당. 
  • 코드를 실행한다.
    • 함수의 호출과 코드의 실행
    • 함수가 호출되면 새로운 함수에 대한 E.C가 만들어지고, 그 안에서 위와 같은 과정을 반복

 

 

https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide/In_depth

 

In depth: Microtasks and the JavaScript runtime environment - Web APIs | MDN

When debugging or, possibly, when trying to decide upon the best approach to solving a problem around timing and scheduling of tasks and microtasks, there are things about how the JavaScript runtime operates under the hood that may be useful to understand.

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/var

 

var - JavaScript | MDN

var 문은 변수를 선언하고, 선택적으로 초기화할 수 있습니다.

developer.mozilla.org

 

'정보 > 프로그래밍 언어' 카테고리의 다른 글

Error와 Exception + Java 개념  (2) 2024.11.05
Java에서의 다형성을 사용한 구현  (0) 2024.09.27