오늘은 JS에서 Call Stack과 Execution Context에 대한 개념을 알아보려고 한다.
먼저 간단한 예시로 운을 띄워 보자
React-Native 빌드를 하면 실행 중에 다음과 에러를 마주할 때가 있다.
꼭 RN 개발이 아니더라도, 모바일이나 웹 개발자라면 한 번쯤 비슷한 에러 메세지를 접해봤을 것이라고 생각된다.
해당 에러는, 에러 메세지에도 나와 있듯, call stack이 넘쳐서 발생한 문제다.
보통은 재귀함수의 조건문에 논리적 헛점으로 인해 생기는 경우가 많다.
그렇다면 여기서 말하는 Call Stack은 무엇일까?
"Call Stack은 인터프리터가 여러 함수를 실행하는 중에, 현재 위치를 추적하도록 도와주는 메카니즘이다."
이렇게만 들으면 무슨 소리인지 잘 이해하지 못 할 수 있다.
간단한 예시와 함께 알아보자.
function first() {
//part 1
second();
//part 2
}
function second() {
console.log("second");
}
first();
제일 먼저 first() 함수가 실행될 것이다.
우리는 이때 이걸 first() 함수가 call stack list에 더해진다고 표현한다.
first()함수의 part1이 실행된 후에 second() 함수가 실행된다.
이때도 second() 함수가 call stack list에 더해진다.
second() 함수가 모두 실행 된 다음, part2 부분이 실행 된 다음 first()가 call stack list에서 제거 되면서 실행이 마무리 된다.
이런 식으로 call stack은 어떤 함수가 현재 실행 중인지 파악하고, 어떤 순서로 실행 될 지를 판단하는데 사용된다.
call stack에는 실행 될 함수와 execution context가 저장 된다.
그럼 execution context에 대해 잠깐 알아보자
Execution Context -> 우리말로 하면 실행환경, 실행문맥 정도 되겠다.
말 그대로 실행할 코드의 "Context"를 지정하는 역할이다.
자바스크립트 엔진은 코드를 실행시키기 위해 3가지 정보를 알고 있어야 한다.
변수 객체 (Variable Object)
변수, 함수 선언, parameter, argument 등 정보를 담는 객체를 말한다.
변수 scope (Scope Chain)
JS 엔진이 렉시컬 스코프를 파악할 때 사용 된다. 특정 변수가 참조 되면, 스코프 체인 안에서 AO(Activation Object)를 차례로 검색해서 scope를 확인한다.
this
자신이 생성할 인스턴스를 가리키는 자기 참조 변수이다.
이와 관련 된 내용을 excution context가 포함하고 있다.
Execution Context는 크게 세 가지 종류가 있다.
이름 처럼 전역에 있는 코드와 관련 된 context다.
앱 내에 있는 모든 JS 코드는 동일한 global execution context 내에서 실행된다.
global object를 생성하고 global object를 참조한다.
실행 시 제일 먼저 call stack에 추가 되며, 앱 종료할 때 call stack에서 없어진다.
함수가 실행되는 Context를 정의한다.
함수가 실행 할 때마다 새로 정의 되며, 함수 시작 시 call stack에 추가되고, 함수 종류 시 call stack에서 삭제 된다.
JS eval 함수를 실행 할 때 참조 되는 context 값이다.
eval 함수는 스트링으로 제공된 코드를 실제로 실행 시킨 후 return 값을 반환한다.
sql injection 처럼 해킹에 사용될 수 있기 때문에, 대부분 사용을 하지 않길 권고하고 있다.
하튼 이렇듯 새로운 코드를 실행해야할 context가 필요하기 때문에, eval execution context가 따로 존재한다.
eval 함수는 잘 사용하지 않기 때문에, 추가 설명은 생략하겠다.
context가 처음 생성 되는 단계다.
실제로 실행 되는 단계다.
creation phase와 상태가 거의 비슷하지만, 변수가 할당된다는 점이 다르다.
JS 엔진이 코드를 한 줄씩 실행하며, 변수에 실제 값에 할당한다.
execution phase가 끝나면 Call Stack에서 Pop해서 제거한다.
CallStack에 함수 및 Execution Context가 추가되는 모습을 도식화 하면 다음과 같다.
https://developer.mozilla.org/en-US/docs/Glossary/Call_stack