Call Stack과 Execution Context 를 알아보자

Jeongkuk Seo
sjk5766
Published in
9 min readMay 11, 2020

--

이 글에서 Call StackExecution Context에 대해 다룹니다. 각 용어는 한국어로 해석하지 않고 영어 그대로 표기합니다.

Execution context

Execution context는 자바스크립트 코드가 실행되는 환경을 의미합니다. 자바스크립트에서 대표적으로 두 가지 타입의 Execution context가 있습니다.

1. Global Execution context
자바스크립트 엔진이 처음 코드를 실행할 때 Global Execution Context가 생성됩니다. 생성 과정에서 전역 객체인 Window Object (Node는 Global) 를 생성하고 this가 Window 객체를 가리키도록 합니다.

위와 같이 아무런 코드가 없더라도 자바스크립트 엔진은 파일을 실행시키는
시점에 아래와 같이 Global Execution Context 를 생성합니다.

2. Function Execution context
자바스크립트 엔진은 함수가 호출 될 때마다 호출 된 함수를 위한 Execution Context를 생성합니다. 모든 함수는 호출되는 시점에 자신만의 Execution Context를 가집니다.

* 자바스크립트 엔진은 처음 코드를 실행할 떄 단 한번 Global Execution Context를 생성하며 함수를 호출할 때 마다 함수를 위한 Execution context를 생성합니다.

call stack

Call Stack은 코드가 실행되면서 생성되는 Execution Context를 저장하는 자료구조 입니다. 엔진이 처음 script를 실행할 때, Global Execution Context를 생성하고 이를 Call Stack에 push합니다. 그 후 엔진이 함수를 호출할 때 마다 함수를 위한 Execution Context를 생성하고 이를 Call Stack에 push 합니다.

자바스크립트 엔진은 Call StackTop에 위치한 함수를 실행하며 함수가 종료되면 stack에서 제거(pop)하고 제어를 다음 Top에 위치한 함수로 이동합니다.

아래와 같은 코드가 있을 때,

Execution Context 는 아래와 같은 흐름으로 Call Stack에 추가(push) 및 제거(pop) 됩니다.

  • step1: 엔진이 처음 자바스크립트 파일을 실행시키며 Global Execution context 를 생성하고 Call Stack에 추가합니다.
  • step2: 엔진이 first 함수 호출코드를 발견하고 first 함수를 위한 Execution context 를 생성하고 Call Stack에 추가합니다.
  • step3: first 함수 내부에서 console.log 함수를 발견하고 이를 위한 Execution context 를 생성하고 Call Stack에 추가합니다.
  • step4: console.log(‘first’) 함수가 종료된 후 Call Stack에서 제거 됩니다.
  • step5: second 함수 호출시에 second 함수를 위한 Execution context 를 생성하고 Call Stack에 추가합니다.
  • step6: second 함수 내부에서 console.log 함수를 발견하고 이를 위한 Execution context 를 생성하고 Call Stack에 추가합니다.
  • step7: console.log(‘second’) 함수가 종료된 후 Call Stack에서 제거 됩니다.
  • step8: second 함수가 종료된 후 Call Stack에서 제거 됩니다.
  • step9: first 함수가 종료된 후 Call Stack에서 제거 됩니다.
  • step10: 모든 코드의 실행이 끝난 뒤에 자바스크립트 엔진은 Call Stack에서
    Global Execution context를 제거합니다.

에러가 발생할 때 보여지는 Stack trace도 이 Call Stack을 참조합니다.

위 코드를 브라우저에서 실행하면 아래와 같은 Stack trace를 얻을 수 있습니다.

a 함수 내부에서 throw 코드 실행 전에 Call Stack은 아래와 같습니다. throw 코드가 실행되면 Call Stack의 Top부터 pop 하여 Stack Trace에 차례대로 기록됩니다.

여기까지 Execution context 가 무엇이고 언제 생성되어 Call Stack에 추가되는지 알아봤습니다. 그럼 이제 Execution context 가 자바스크립트 엔진에 의해 어떻게 생성되는지 알아보겠습니다.

Execution context 생성 과정

Execution Context의 생성은 두 단계로 나뉩니다.

1. Creation Phase (생성 단계)
2. Execution Phase (실행 단계)

아래 코드를 위 두 단계로 나누어 살펴보겠습니다.

자바스크립트 엔진에 의해 파일이 처음 실행될 때 Global Execution context 가 생성됩니다. Global Execution context 가 만들어지는 과정에서 Creation과 Execution 두 단계를 거칩니다.

아래 그림은 두 단계에서 Global Execution context 의 정보를 나타냅니다.

Global Creation phase(생성 단계) 에서 자바스크립트 엔진은,

  • Global Object를 생성한다.
  • this 객체를 생성한다.
  • 변수와 함수를 위한 메모리를 준비한다.
  • 변수에는 undefined를 할당하고 (var 변수 경우만) 함수 선언문은 실제로 메모리에 할당한다.

그 다음 단계인 Execution phase(실행 단계)에서 자바스크립트 엔진은 코드를 한 줄씩 실행하고 변수에 실제 값을 할당합니다.

위 코드에 로그를 출력해 보겠습니다. 처음 console.log가 실행되는 시점은 이미 Global Creation phase 단계가 끝난 시점입니다. 따라서 var로 선언된 변수는 undefined를, 함수는 메모리에 있는 참조 값을 가지게 됩니다.

console.log(name)    // undefined
console.log(age) // undefined
console.log(getUser) // [Function: getUser]
var name = 'seo';
var age = 31;
function getUser() {
return {
name: name,
age: age
}
}

여기서 자바스크립트 엔진의 Creation phase(생성 단계) 때문에 전역 var 변수, 함수 선언문에 대해 우리가 알고 있는 hoisting이 발생하는 것을 알 수 있습니다.

위에서 설명한 것은 Global Execution context 입니다. 그럼 이번에는 Function Execution context 의 두 단계(Creation phase, Execution phase)를 보겠습니다.

다행히도 Creation phase단계에서 Function Execution context Global Execution context 는 하나의 차이점만 가지고 있습니다. Function Creation phase(생성 단계) 에서 자바스크립트 엔진은,

  • arguments 객체를 생성한다.
  • this 객체를 생성한다.
  • 변수와 함수를 위한 메모리를 준비한다.
  • 변수에는 undefined를 할당하고 (var 변수 경우만) 함수 선언문은 실제로 메모리에 할당한다.

유일하게 Function Execution context 에서 다른점은 전역객체 대신 arguments 객체를 생성한다는 점입니다. 그 외 역할은 동일합니다.

코드를 통해 Function Execution context Creation phase, Execution phase 를 확인해 보겠습니다.

Global Execution context 를 설명할 때와 다른점은 11번 라인에서 함수를 호출하고 인자를 전달하는 것, 그리고 함수 내부에 변수가 있다는 점입니다.

코드가 실행되고 자바스크립트 엔진이 12번 라인에서 함수 호출 코드를 만나면 getUser 함수를 위한 Execution context 를 생성합니다. 이 때 Creation phase, Execution phase 는 아래와 같습니다.

함수가 호출되면 Creation phase단계에서 arguments와 this 객체를 생성하고함수 내부의 변수와 함수에 대한 호이스팅을 수행합니다. Execution phase(실행 단계)에서 엔진이 코드를 한 줄씩 실행하고 변수에 실제 값을 할당합니다.

자바스크립트 엔진은 함수를 호출할 때 Execution context 를 생성하고 Call Stack에 추가합니다. 함수가 종료된 후 Creation phase, Execution phase 두 단계가 끝나면 자바스크립트 엔진이 Call Stack에서 해당 함수를 제거(pop) 하게 됩니다.

참고 자료

https://medium.com/@gaurav.pandvia/understanding-javascript-function-executions-tasks-event-loop-call-stack-more-part-1-5683dea1f5ec

https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript-1c9ea8642dd0

https://tylermcginnis.com/ultimate-guide-to-execution-contexts-hoisting-scopes-and-closures-in-javascript/

--

--