자바스크립트의 호출 스택과 이벤트 루프.
자바스크립트 코드 동작을 이해하려면 필수적으로 알아야 하기 때문에 정리를 해두려고 한다.
우선 호출스택과 이벤트 루프를 알기 전에 실행 컨텍스트 Excution Context를 알아보자.
실행 컨텍스트는 아마 많이 들어봤을 것 같은데 scope, hoisting, this, function 등의 동작 원리를 담고 있는 자바스크립트의 핵심 원리다.
context를 한국어로 번역하면 문맥 이다. 코드의 실행환경 이라고 이해하면 쉽다.
우선 제일 먼저 전역 컨텍스트 가 존재한다. 처음 스크립트를 실행해서 종료될 때 까지 유지 된다. 그 다음은 함수 컨텍스트, 함수를 호출할 때 마다 함수 컨텍스트가 하나씩 더 생긴다.
컨텍스트 생성 시 컨텍스트 안에 변수 객체(arguments, variables), scope chain, this 가 생성된다.
컨텍스트 생성 후 해당 컨텍스트에 변수가 없다면 스코프 체인을 따라 올라가며 찾게 된다.
전역 컨텍스트는 함수의 인자인 arguments가 없고 variables만 있다.
scope chain은 원래 자신과 상위 스코프의 변수 객체를 의미하는데 전역 컨텍스트는 상위 스코프가 없기 때문에 자기 자신의 전역 변수객체만 있다.
this 는 따로 설정되어 있지 않다면 window이다
그 다음은
함수를 실행하려면 스택에 함수를 집어넣게 되고 함수에서 리턴이 일어나면 스택의 가장 위쪼겡서 해당 함수를 꺼내게 된다. 이것이 전부!
function first() {
second();
}
function second() {
third();
}
function third() {
}
first();
third();
Uncaught RangeError: Maximum call stack size exceeded
호출 스택이 가득 찼을 때 위와 같은 에러가 발생한다.
재귀함수 recursive funtion 를 사용할 때 주로 발생한다.
자바스크립트와 노드에서 사용되는 이벤트 루프. 이 또한 아주 중요!!
스레드는 어떤 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 의미한다.
일반적으로 한 프로그램은 하나의 스레드를 가지고 있다. (싱글스레드) 그러나 프로그램 환경에 따라 여러 개의 스레드를 실행할 수 있다. (멀티스레드)
여러 작업이 마치 동시에 일어나는 것처럼 보이는 것
자바스크립트를 싱글스레드라고 부르는 이유는 자바스크립트의 메인 스레드인 이벤트 루프가 싱글스레드이기 때문이다.
싱글스레드는 프로그램이 작동되는 동안 한번에 하나의 작업만을 수행할 수 있다.
그러나 이벤트 루프만 독립적으로 실행되지 않고 웹 브라우저나 Nodejs같은 자바스크립트 런타임 환경은 멀티 스레드이다. 따라서 자바스크립트는 비동기 코드가 동작한다. (대표적인 예로 3초 후에 로그를 찍을 때 프로그램이 멈추지 않고 동작하다가 로그가 찍힌다)
자바스크립트의 런타임은 메모리 힙(Memory Heap)과 콜스택(Call Stack) 으로 구성되어 있다.
메모리 힙은 메모리 할당을 담당, 콜스택은 코드가 호출될 때 스택으로 쌓이는 곳
메인 스레드에서 호출되는 함수들은 콜스택에 쌓이게 되고 이 함수들은 LIFO 방식으로 실행된다.
기본적인 작업들은 위에 콜스택 설명할 때 말했듯이 함수 실행 -> 실행 종료 후 콜스택에서 제거 가 반복 된다.
그러나 비동기 작업은 다르다.
자바스크립트는 한번에 하나밖에 할 수 없다. 다른 코드를 실행시키는 동안 Ajax 요청, setTimeout 역시 할 수 없다.
우리가 이걸 동시에 할 수 있는 이유는 브라우저가 단순 런타임 이상을 의미하기 때문이다. 브라우저는 Web API 를 통해 자바스크립트에서 호출할 수 있는 스레드를 제공해준다. 여기에 동시성이 들어온다. (Node는 C++ API)