Skip to content

Tags

On this page

JavaScript 실행 컨텍스트

실행 컨텍스트(execution context)는 짧게 '컨텍스트'라 부른다. 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다. 변수나 함수의 실행 컨텍스트는 변수나 함수가 어떻게 행동하는지를 규정한다. 자바스크립트는 어떤 실행 컨텍스트가 활성화되는 시점에 선언된 변수를 끌어올리고, 외부 환경 정보를 구성하고, this 값을 설정하는 등 동작을 수행하게 된다. 그래서 다른 언어에서는 발견할 수 없는 특이한 현상들이 발생하기도 한다.

지금부터 실행 컨텍스트의 동작을 통해 자바스크립트에서 소스코드가 어떻게 실행되는지 알아보자.

소스코드의 평가와 실행

모든 소스코드는 실행 전에 평가 과정을 거치면서 실행을 위한 준비를 한다. 자바스크립트 엔진은 "소스코드 평가"와 "소스코드 실행"의 두 과정을 처리한다.
평가 과정에서는 실행 컨텍스트를 생성해 변수, 함수 등의 선언문만 먼저 실행해서 생성된 변수와 함수 식별자를 키로 실행 컨텍스트가 관리하는 스코프(렉시컬 환경의 환경 레코드)에 등록한다.

평가 과정이 끝나면 비로소 선언문을 제외한 소스코드가 순차적으로 실행되기 시작한다. (런타임이 시작된다.) 이때 소스코드 실행에 필요한 정보, 즉 변수나 함수의 참조를 실행 컨텍스트가 관리하는 스코프에서 검색해서 취득한다. 그리고 변수 값의 변경 등 소스코드의 실행 결과가 다시 실행 컨텍스트가 관리하는 스코프에 등록이된다.

var x;
x = 1;

위 코드는 아래 그림과 같이 실행 컨텍스트를 통해 처리된다. 우선 자바스크립트 엔진이 소스코드 평가 과정에서 변수 선언문 var x;를 먼저 실행하고 이때 생성된 식별자 x가 실행 컨텍스트가 관리하는 스코프에 등록되어 undefined로 초기화된다. 평가 과정이 끝나면 실행 과정이 시작된다. 이때 실행 컨텍스트가 관리하는 스코프에 x가 등록되어 있는지 확인을 한다. 등록되어 있다면 선언된 변수이므로 값을 할당하고 할당 결과를 다시 실행 컨텍스트에 등록해 관리한다.

source code execution
source code execution.png

실행 컨텍스트 스택 (콜 스택)

자바스크립트는 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성한다. 생성된 실행 컨텍스트는 스택으로 관리된다. 이를 실행 컨텍스트 스택이라 부르는데, 콜 스택이라고 부르기도 한다. 가장 위에 쌓여있는 컨텍스트와 관련 있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장한다.
여기서 말하는 컨텍스트를 구성하는 '동일한 환경'에는 다음과 같은 것들이 있다.

  • 전역 코드
    • 전역에 존재하는 코드
  • 함수 코드
    • 함수 내부에 존재하는 코드
  • eval 코드
    • eval 함수에 인수로 전달되어 실행되는 코드
  • 모듈 코드
    • 모듈 내부에 존재하는 코드

다음 코드를 살펴보자.

const x = 1;
const y = 2;
function sum(a, b) {
const x = 100;
const y = 200;
console.log(x + y + a + b);
}
sum(x, y); // 303
console.log(x + y); // 3

execution context stack1
execution-context-stack1.png

  1. 앞에서 살펴본 것과 같이 자바스크립트 엔진은 우선 전역 코드를 평가하고 실행을 위한 준비를 한다. 선언문을 먼저 실행해 그 결과가 실행 컨텍스트가 관리하는 전역 스코프에 등록한다.
  2. 전역 코드 평가가 끝이나면 전역 코드가 순차적으로 실행된다. 이때 변수에 값이 할당되고 함수가 호출된다. 함수가 호출되면, 전역 코드의 실행을 일시 중단하고 코드 실행 순서를 변경해 함수 내부로 진입하게 된다.
  3. 함수 내부로 진입하면 함수 내부의 문들을 실행하기 전에 함수 코드 평가 과정을 거친다. 이때 매개변수와 지역 변수 선언문이 먼저 실행되고, 그 결과가 실행 컨텍스트가 관리하는 지역 스코프에 등록된다. 함수 내부에서는 arguments 객체가 생성되어 실행 컨텍스트가 관리하는 지역 스코프에 등록되고, this 바인딩도 결정된다.
  4. 함수 코드 평가 과정이 끝이나면 함수 코드가 순차적으로 실행된다. 값이 할당되고 여기서는 console.log 메서드를 호출하기 위해 식별자인 console스코프 체인을 통해 검색한다. console.log 메서드가 실행되고 나면, 함수 호출 이전으로 되돌아가 전역 코드 실행을 계속한다.

렉시컬 환경

렉시컬 환경(Lexical Environment)은 식별자와 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 참조를 기록하는 자료구조이다. 렉시컬 환경은 실행 컨텍스트를 구성하는 컴포넌트다. 콜 스택이 코드의 실행 순서를 관리한다면 렉시컬 환경은 스코프와 식별자를 관리한다.

실행 컨텍스트는 LexicalEnvironment 컴포넌트와 VariableEnvironment 컴포넌트로 구성된다. 처음에는 두 컴포넌트가 동일한 렉시컬 환경을 참조하지만, LexicalEnvironment는 변경 사항이 실시간으로 반영된다.

두 컴포넌트의 내부는 다음과 같이 구성되어 있다.

  1. Environment Record 스코프에 포함된 식별자를 등록하고 등록된 식별자에 바인딩된 값을 관리한다.
  2. Outer Environment Reference 상위 스코프를 가리킨다. 해당 컨텍스트를 생성한 소스코드를 포함하는 상위 코드의 렉시컬 환경을 말한다. 스코프 체인을 구현한다.

실행 컨텍스트의 객체

실행 컨텍스트는 3가지 프로퍼티를 소유한다.

  • Variable Object 변수 객체
    • 변수
    • 매개변수(paramter), 인수(arguments)
    • 함수 선언(함수 표현식은 제외)
  • Scope chain 스코프 체인
  • this value

참고

Edit this page
Last updated on 3/2/2022