목차
지금까지는 자바스크립트의 기본까지 알아봤고 이제는 한 단계 더 나아갈 차례이다. 자바스크립트의 동작 원리에 관한 주요 토픽에 대해 공부해 본다.
자바스크립트의 9가지 특징
파이썬을 공부한 적이 있기에 이름은 익숙한 개념들이 많지만 볼 때마다 새롭게 느껴지는 놀라운 지점…^^;;;;;
- 고수준(High-level)
- 자바스크립트는 Python과 같은 고수준 언어이다.
- 가비지 컬렉터(Garbage-collected)
- 자바스크립트 엔진은 내부에서 가비지 컬렉터를 끊임없이 동작시킨다.
- 인터프리터 또는 JIT(Interpreted or just-in-time(JIT) compiled)
- 자바스크립트는 인터프리터 언어였지만, 모던 자바스크립트는 JIT 컴파일을 사용한다.
- 멀티 패러다임(Multi-paradigm)
- 자바스크립트는 다양한 프로그래밍 패러다임을 지원한다.
- 프로토타입 기반 객체 지향(Prototype-based object-oriented)
- 자바스크립트는 원형 객체(프로토타입)를 복제하여 새로운 객체를 생성하는 프로토타입 기반 객체 지향 언어이다.
- 자바스크립트에서 단순 원시 타입(simple primitive)인 문자열, 숫자, 불리언, null, undefined를 제외한 모든 타입은 객체다.
- 자바스크립트의 객체는 원형 객체(Object.Prototype)로 부터 생성되며, 생성된 객체는 원형에 대한 프로토타입 링크(
__proto__
)를 갖게 된다.
- 일급 함수(First-class Function)
- 자바스크립트에서 함수는 일급 객체이므로 함수의 파라미터로 사용하는 등의 동작이 가능하다.
- 동적(Dynamic)
- 자바스크립트는 변수 선언시 데이터 타입을 지정할 필요가 없고, 변경도 가능한 동적 언어이다.
- 싱글 스레드(Single-threded)
- 자바스크립트는 싱글 스레드 기반으로 동작한다.
- 논블로킹 이벤트 루프(Non-blocking event loop)
- 자바스크립트는 여러 작업이 동시에 진행되도록 하기 위해 이벤트 루프를 사용한다.
자바스크립트 엔진(JavaScript Engine)과 런타임(Runtime)
- 자바스크립트 엔진은 자바스크립트 코드를 실행하는 프로그램을 의미한다.
- 각각의 브라우저는 저마다 자바스크립트 엔진을 가지고 있다.
- e.g. google V8 engine은 크롬과 노드에서 사용됨
- JS 엔진은 콜스택(Call Stack)과 힙(Heap)을 가지고 있다.
- 콜스택은 JS 코드가 실행되는 공간이다.
- 힙은 메모리상에서 JS 객체들이 존재하는 공간이다.
JIT란?
- 코드가 실행되는 방식은 크게 두가지로 나눠볼 수 있다.
- 1. 컴파일(Compilation)
- 소스코드 ➡️ 머신코드 파일(portable binary file) ➡️ 프로그램 실행
- 소스코드를 머신코드로 변환하는 컴파일링 과정을 거친 후에 코드를 실행한다.
- 2. 인터프리터(Interpretation)
- 코드를 한줄씩 읽어가며 (여전히 머신코드로 변환하여야 함) 실행한다.
- 자바스크립트가 처음 등장했을 때는 인터프리터 언어였다.
- 1. 컴파일(Compilation)
- 인터프리터 언어는 컴파일 언어보다 느릴 수 밖에 없다. 더 빠른 웹을 위해서는 새로운 방식이 필요했다.
- 모던 자바스크립트는 JIT(Just-in-time) 컴파일 방식(컴파일과 인터프리터의 믹스)으로 동작한다.
- 소스코드 ➡️ 머신코드(not a portable file) ➡️ 실행
- JS 엔진의 컴파일과 실행 과정
- Parsing: AST로 변환 ➡️ Compilation: 머신코드로 컴파일 ➡️ Execution
- 실행 중에도 최적화(Optimization)를 거치며 다시 컴파일을 진행한다.
- 최적화는 특별한 스레드에서 진행되어 우리가 코드를 통해 접근할 수 없다.
- 따라서 JS가 인터프리터 언어라고 말할 수는 없다.
런타임
- 런타임이란 자바스크립트를 실행하기 위해 필요한 모든 것들이 포함된 컨테이너를 의미한다.
- e.g. 브라우저
- 브라우저의 런타임에는 엔진(Call Stack, Heap), Web API(DOM, Timers, Fetch API…/브라우저 제공), Callback Queue(click, timer, data…) 등이 포함되어 있다.
- Event Loop
- 콜백 큐에서 이벤트를 꺼내 콜스택에 넣어줘서 코드를 실행하게 하는 프로세스
- node.js 와 같이 브라우저 외에도 자바스크립트 런타임이 존재할 수 있다.
- node.js 런타임에는 브라우저가 제공하는 Web API가 포함되어 있지 않다.
- 대신 C++ bindings과 쓰레드 풀이 존재한다.
실행 컨텍스트(Execution Contexts)
- 자바스크립트가 실행되는 추상적인 환경을 의미한다.
- 소스코드가 실행되기 위해 필요한 모든 정보(소스코드, 변수, 인자…)들이 들어 있다.
컴파일 후의 실행 순서
- 1. Creation of global execution context(for top-level code)
- function 안에 있지 않은 코드들(변수 선언 등)
- 오직 하나의 global execution context (EC) 존재
- Default Context
- 2. Execution of top-level code(inside global EC)
- 3. Execution of functions and waiting for callbacks
- One execution context per functions
- 함수의 콜마다 새로운 EC가 생성된다.
- 모든 EC는 콜 스택에 들어간다.
실행 컨텍스트에 포함된 것들
- Creation phase에 생성되는 것들
- Variable Environment
let
,const
,var
, functions,arguments
objects
- Scope chain
this
keyword
- Variable Environment
- Arrow 함수는 자체적인 arguments, this 를 갖지 않는다. (가장 가까운 레귤러 함수의 것을 가짐)
콜 스택(The Call Stack)
- 콜 스택은 Execution Context들이 쌓이는 공간을 의미한다.
- 스택의 가장 위에는 현재 실행되고 있는 EC가 존재한다.
- 하나의 EC 실행이 끝날 때 마다 스택에 쌓인 컨텍스트가 제거되고 아래 위치한 EC로 이동
- 결국 Global EC가 마지막에 실행된다.
- 브라우저 탭을 종료시키기 전까지 대기(stay) 상태
- 탭을 종료시키면 Global EC도 제거된다.