실행 컨텍스트 : 자 이게 너가 사용할 수 있는 친구들이야

const a = 1;

function sum () {
  return a + 3;
}

console.log(sum());

여기 간단한 덧셈을 통해 결과를 출력하는 코드가 있다고 하자.

이 코드의 출력값은 얼마일까?

 

인간의 관점으로 본다면 sum이라는 함수에 a라는 변수는 윗줄에서 선언되었고,

1이라는 값이 할당되었기에 3을 더해 4라는 결과값을 출력한다고 바로 생각할 수 있다.

 

그러나 자바스크립트 엔진은 코드를 인간처럼 직관적으로 코드를 해석할 수 없기에

실행에 필요한 다양한 정보가 있어야 하는데 그 정보들을 가진 객체를 실행 컨텍스트라고 한다.

 


 

실행 컨텍스트

실행할 코드에 제공할 환경 정보들을 모아놓은 객체로,
자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념이다.

 

실행 컨텍스트에 대해 코어 자바스크립트 저자 정재남 님이 정의하신 내용을 발췌했다.

더 짧게 요약하자면 실행 컨텍스트는 코드가 실행될 때 제공되는 정보 객체다.

 

맨 위의 예시를 통해 설명하자면, sum이라고 하는 함수가 실행될 때,

그 안에 어떤 변수가 있고, 해당 변수는 출처가 어디인지 표시해 놓은 객체라고 생각하면 되겠다.

 

언제 만들어짐?

실행 컨텍스트는 코드가 실행될 때 만들어지는데 크게 2가지 상황에서 만들어진다.

1. 자바스크립트 코드가 실행될 때 (전역 컨텍스트)
2. 함수가 실행될 때 (함수 컨텍스트)

 

그래서 가장 먼저 생성이 되는 게 전역 컨텍스트고,

함수의 호출에 따라서 여러 함수 컨텍스트가 생성되고 실행이 끝나면 사라지고를 반복하다가

모든 코드의 실행이 끝나면 그제야 전역 컨텍스트가 사라지게 된다.

 

그럼 실행 컨텍스트가 어떤 정보로 구성되어 있는지도 한번 알아보자.

 

실행 컨텍스트의 구조

실행 컨텍스트는 크게 3가지 정보가 담겨 있다.

 

첫 번째로 VariableEnvironment, 직역하면 변수 환경인데

현재 컨텍스트 내의 식별자들 (변수, 함수 등)에 대한 정보와

해당 코드가 실행될 때 외부 환경에 대한 정보도 가지고 있다.

 

두 번째로 LexicalEnvironment,

직역하면 어휘적 환경인데여러 해석을 통해 이해한 바로는 변수가 참조하는 범위 환경이라고 이해하고 있다.
이 정보에는 첫 번째와 마찬가지로 컨텍스트 내의 식별자들과 외부 환경에 대한 정보를 담고 있는데

VariableEnvironment와 다른 점은 변경 사항이 실시간으로 반영된다는 점이다.

반대로 VariableEnvironment는 처음 생성 됐을 때 가지고 있던 정보를 그대로 갖고 있다.

 

위 두 가지 구조는 Environment Record (환경 레코드)와

Outer Environment Reference (외부 환경 참조)로 나뉘게 되는데,

환경 레코드에는 현재 컨텍스트의 변수와 함수 선언을 저장하고,

외부 환경 참조 부분에는 상위 렉시컬 환경에 대한 참조를 가지고 있어서, 스코프 체인이 생기게 된다.

 

세 번째로는 ThisBinding인데, this 식별자가 바라보고 있는 대상 객체를 의미한다.
차후에 this라는 개념에 대해서도 다룰 예정이라 일단 이번에는 이렇게 넘어가자.

 

728x90

 

실행 컨텍스트가 동작하는 법

실행 컨텍스트는 자바스크립트 코드가 실행될 때, 혹은 함수가 실행될 때 생성되고,

실행 환경에 따라 전역 혹은 함수 내에 있는 다양한 식별자들의 정보와 외부 환경에 대한 정보를 갖게 된다.

 

자바스크립트 코드 내에서는 여러 가지 함수가 생성되고 호출되고,

함수 안에서 또 다른 함수가 호출되고 하는 다양한 과정이 진행되는데,

이러한 흐름에서 실행 컨텍스트가 어떻게 생성되고 소멸되는지 그 사이클에 대해서 알아보자.

 

실행 컨텍스트는 논리적 스택 구조를 가지게 되는데

여기서 스택이라고 하는 것은 마치 상자에 물건을 넣고 빼는 것처럼

실행 컨텍스트들이 쌓이고, 가장 나중에 쌓인 컨텍스트부터 실행되는 구조를 의미한다. (LIFO)

 

var a = 1;

function outer () {
  var a = 2;
  inner();
}

function inner () {
  console.log(a);
}

outer();

위의 예시를 통해 설명하자면

가장 먼저 자바스크립트 코드가 실행되면 전역 컨텍스트가 스택에 쌓이게 된다.

그때, 전역 컨텍스트에는 변수 a와 함수 outer, inner의 정보를 갖게 된다.

 

그다음 outer 함수가 호출될 때, outer 컨텍스트가 스택에 쌓이게 된다.

outer 함수는 내부에 있는 변수 a의 정보와 외부 환경인 전역 컨텍스트의 정보를 갖게 된다.

 

outer 함수 안에 inner 함수가 호출되면, inner 컨텍스트가 스택에 쌓이게 된다.

inner 함수 안에서 console.log(a)를 실행하고 내부 동작이 끝나면 inner 컨텍스트는 스택에서 사라지게 된다.

그 후 outer 함수로 돌아와 내부의 코드 실행을 마치면 outer 컨텍스트도 스택에서 사라지게 된다.

마찬가지로 자바스크립트의 전체 코드가 실행되면 전역 컨텍스트도 스택에서 사라지게 된다.

 

위의 설명을 그림으로 표시한 부분이다.

스택을 상자에 물건을 넣고 빼는 걸로 설명한 게 이 그림을 보고 얘기한 거다.

LIFO라고 적어놨는데 이건 Last In, First Out의 줄임말이다.

자료구조 중에 스택과 비교되는 큐 (Queue)라는 것도 있는데 이건 FIFO이다.

 

나중에 자료구조에 대해서도 다뤄보자.

 

var a = 1;

function outer () {
  var a = 2;
  inner();
}

function inner () {
  console.log(a);
}

outer();

다시 예시 코드로 돌아와서, inner의 출력값으로는 어떤 값이 나올까? 1일까 2일까?

 

지금까지 알아본 내용을 토대로 한다면

inner 함수가 outer 함수 내에서 호출됐기 때문에 inner 컨텍스트가 생성될 때,

외부 환경으로 outer 함수를 참조할 것이고, 스코프도 outer 범위라서 2가 출력되지 않을까 할 텐데

 

1이 출력되는 이유는, inner 함수가 생성되는 부분을 보면 알 수 있다.

inner 함수가 생성될 때의 외부 환경은 전역 스코프다.

 

이 말을 통해 알 수 있는 건 실행 컨텍스트의 외부 환경 참조는 함수가 호출될 때 정해지는 것이 아닌

선언될 때 정해지는 값이다.

 

그렇기에 inner 함수가 선언될 때, 외부 환경은 전역을 가리키고 있어서

inner 함수 내부에서 출력한 a는 1이라는 값을 출력하게 되는 것이다.

 

Summary

실행 컨텍스트에 대해 요약해 보자면 다음과 같다.

 

실행 콘텍스트는 코드가 실행될 때 실행에 도움을 주는 다양한 정보를 가지고 있는 객체다.

실행 컨텍스트는 VariableEnvironment, LexicalEnvironment, ThisBinding으로 구성되어 있고

VariableEnvironment와 LexicalEnvironment는 컨텍스트 내부 식별자 정보와 외부 환경의 데이터를 가지고 있다.

 

VariableEnvironment와 LexicalEnvironment는 다시

Environment Record와 Outer Environment Reference로 나뉘게 되는데,

Environment Record가 컨텍스트 내부 식별자 정보를 담당하고,

Outer Environment Reference가 상위 렉시컬 환경에 대한 정보를 담당하는데,

Outer Environment Reference 같은 경우 호출될 때의 환경이 아닌 선언될 때의 환경 정보를 가지고 있다.

 


 

함께 읽으면 좋은 글 리스트

var, let, const : 자바스크립트 변수 선언 3 대장

Scope : 변수, 너에게 닿을 수 있는 그 범위

호이스팅 : 변수, 함수 끌어~ 올려!

This : 이거라며.. 왜 다르냐고

 

포스팅 작성에 참고한 감사한 글들

ggong님 블로그 : 자바스크립트의 실행 컨텍스트

권준혁 님 블로그 : Javascript Execution Context

휴먼스케이프 블로그 : 자바스크립트 실행 컨텍스트