Web/JavaScript

[JavaScript] 실행 컨텍스트와 스코프 체인

Hov 2021. 5. 13. 21:33
실행 컨텍스트(Execution Context)란?

context는 한국어로 문맥 이라는 뜻을 가진다. 문맥의 정확한 정의는 그럼 무엇일까?

문맥 어떤 주어진 언어표현이 나타나는 부분과 연관이 되는 언어적인 맥락 또는 환경. (네이버 사전)

실행 컨텍스트자바스크립트 코드가 실행되기 위해서 필요한 맥락과 환경을 context라고 한다.
컨텍스트에는 세 가지 종류가 있다.

Context의 종류

1. Global Execution Context (전역 컨텍스트)
  - 코드가 글로벌로 실행이 될 때의 환경
  - 자바스크립트는 싱글 스레드 언어이기 때문에 전역 컨텍스트는 딱 하나만 존재

2. Functional Execution Context (함수 컨텍스트)
  - 함수가 호출이 되어 실행이 될 때 실행되고 있는 함수에 대해서 생성되는 컨텍스트
  - 함수 내부의 this, 지역 변수 등

3. Eval (Eval 컨텍스트)
  - Eval 함수가 실행될 때 생성되는 컨텍스트 (MDN에서도 사용하지 않을것을 권고하기 때문에 사용 X)

자바스크립트 엔진은 코드를 실행하기 위해 현재 어떤 문맥에서 실행을 하고 있는지, 이변수는 어떤 변수를 가리키는지 등 여러가지 정보를 알고 있어야 한다. (변수, 함수 선언, 스코프, this)

때문에 이와 같이 실행에 필요한 정보를 형상화 하고 구분하기 위해
자바스크립트 엔진은 실행 컨텍스트를 객체 형태로 만들어 실행 컨텍스트 스텍에 관리한다.

var x = 'xxx';

function foo () {
  var y = 'yyy';

  function bar () {
    var z = 'zzz';
    console.log(x + y + z);
  }
  bar();
}
foo();

위의 코드를 실행하면 아래와 같이 실행 컨텍스트 스택이 생성, 소멸된다. 현재 실행 중인 컨텍스트에서 이 컨텍스트와 관련이 없는 함수가 실행이 되면 새로운 컨텍스트가 생성되고, 제어권이 새로운 컨텍스트로 이동한다.

자바스크립트 콜스텍과 상당히 유사한 구조다.

  1. 전역 실행 컨텍스트는 전역 코드로 컨트롤이 진입하면서 생성이 되어 실행 컨텍스트 스택 제일 하단에 쌓인다.
    그리고 애플리케이션이 종료될 때(웹 페이지에서 나가거나 브라우저를 닫을 때)까지 유지된다.
  2. 함수를 호출(선언x)하면 해당 함수의 실행 컨텍스트가 생성되며 직전에 실행된 코드 블록의 실행 컨텍스트 위에 쌓인다.
  3. 함수 실행이 끝나면 해당 함수의 실행 컨텍스트를 파기하고 직전의 실행 컨텍스트에 컨트롤을 반환한다.

실행 컨텍스트 객체

실행 컨텍스트의 객체는 Creatcion, Execution의 두 단계로 이루어진다. Creation은 말 그대로 실행 문맥을 생성, Execution은 실행이 될 때 변수에 대한 값이 할당되고 코드가 실행된다.

아래에서 설명하는 구조는 ES3를 기반으로 하고 있다.
기본적으로 컨텍스트의 개념에 대해 먼저 정리할 필요가 있기 때문에 ES5, ES6버전의 컨텍스트도 다음 포스트에서 다뤄보겠다.

실행 컨텍스트는 기본적으로 변수객체, 스코프체인, this 세가지의 프로퍼티를 갖고 있다.

EC는 변수, 스코프 체인, this를 갖는다

1. 변수 객체 (Variable Object / VO)

일단 실행 컨텍스트가 생성되면 자바스크립트 엔진은 실행에 필요한 여러 정보를 담을 변수 객체를 생성한다.

변수 객체는 var, parameter, argument, 함수 선언의 정보를 담는다. * 이 때 일어나는 현상이 호이스팅!?
위의 코드에서 생성된 전역 EC와 foo() EC를 살펴보면 전역 객체의 VO는 전역에 선언 된 전역 변수와 전역 함수를 소유하는 전역 객체(GO)를 가리키고, 함수 컨텍스트의 VO는 매개변수, 인수등의 정보를 배열의 형태로 담고 있는 활성 객체 (AO)를 가리킨다.

여기서 값을 직접 갖지 않고 매핑(참조)를 하고 있다는 것을 주의해야한다.

2. 스코프 체인 (Scope Chain / SC)

스코프 체인(Scope Chain)은 전역 객체와 중첩된 함수 스코프의 레퍼런스가 차례대로 저장 된 리스트다.
해당 전역, 함수가 참조할 수 있는 변수, 함수 선언 등의 정보를 담고 있는 GO, AO리스트를 가리킨다.
현재 실행 컨텍스트의 AO 레퍼런스가 리스트의 첫 번째에 위치 해 있고, 마지막 값은 GO를 가리킨다.


함수가 중첩 상태일 때 하위 함수 내에서 상위 함수의 스코프를 갖는 변수나, 함수에 접근 할 수 있는데 이것이 바로 스코프 체인이 있기에 검색이 가능 한 것이다.
함수 실행 중에 변수를 만나면 그 변수를 리스트의 처음(현재 스코프) 부터 상위의 스코프로 검색을 이어가는 것이다. 결국 끝(전역)까지 검색에 실패한다면 정의 되지 않은 변수에 접근 한 것으로 판단해 Reference 에러를 발생 시킨다.

렉시컬 스코프 (Lexical Scope)
현재 문법이 갖고 있는 스코프를 말하는데, 엔진은 스코프 체인을 통해 함수가 선언이 되었을 때 렉시컬 스코프를 파악한다.

3. this

this 프로퍼티에는 함수가 호출 될 때 this의 값이 할당된다. 즉 함수를 어떻게 호출하냐에 따라 this가 가리키는 대상이 달라질 수 있다는 것이다. 함수와 객체의 관계가 느슨한 자바스크립트에서 this는 이 둘을 연결 시켜주는 역할을 한다. 자세한 내용은 다음 포스트를 참고하자.

 

이제 실행 컨텍스트의 개념과 구조에 대해 어느정도 감이 잡힌 듯 하다. 다음에는 ES5, ES6에서 어떻게 실행 컨텍스트의 구조가 바뀌었는지 한번 자세히 다뤄봐야겠다.

참고

 

Execution Context | PoiemaWeb

Execution Context(실행 컨텍스트)는 scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트의 핵심원리이다. 실행 컨텍스트를 바로 이해하지 못하면 코드 독해가 어려워지며 디버

poiemaweb.com

ES5버전의 실행 컨텍스트에 대해 설명하는 글