JS 실행 컨텍스트

실행 컨텍스트는 식별자, 스코프, 호이스팅, 클로저 등의 동작 원리를 담고 있는 자바스크립트의 핵심 개념이다. 동적 언어로서의 자바스크림트 성격을 잘 파악할 수 있다.

실행 컨텍스트: 실행할 코드에 제공할 환경 정보들을 모아놓은 객체.

실행 가능한 코드

ECMAScript 사양은 실행 가능한 코드(Executable Code)를 4가지 유형으로 구분한다. 각 유형마다 실행 컨텍스트를 생성하는 과정과 관리 내용이 다르기 때문에 구분해둔다.

실행 가능한 코드 설명
전역 코드 (Global code) 전역에 존재하는 텍스트 코드. 전역에 정의된 함수, 클래스 등의 내부 코드는 포함되지 않음. 전역 코드는 전역 스코프를 생성 해야 하며 전역 객체와 연결되어야 한다.
함수 모드 (Function code) 함수 내부에 중첩된 함수, 클래스 등의 내부 코드는 포함되지 않음. 함수 코드는 지역 스코프를 생성 해야 하며 생성된 지역 스코프는 스코프 체인의 최상위인 전역 스코프에서 시작하는 스코프 체인의 일원으로 연결 되어야 한다.
eval 코드 (Eval code) 빌트인 전역 함수인 eval 함수에 인수로 전달된 텍스트 코드. eval 코드는 엄격 모드(strict mode)에서 자신만의 독자적인 스코프를 생성한다.
모듈 코드 (Module code) 모듈 내부에 존재하는 텍스트 코드. 모듈 내부의 함수, 클래스 등의 내부 코드는 포함되지 않음. 모듈 코드는 모듈 별로 독립적인 스코프를 생성한다.
실행 가능한 코드의 평가와 실행
  1. 실행 가능한 코드는 실행에 앞서 평가 과정을 거친다.
  2. 평가 과정에서 실행 컨텍스트가 생성된다.
  3. 변수, 함수, 클래스 등의 선언문이 평가된다. 그 결과는 생성된 실행 컨텍스트에 등록된다.
  4. 평가 과정이 끝나면 선언문을 제외한 코드가 순차적으로 실행된다. 이때 코드 실행에 필요한 정보를 실행 컨텍스트에서 취득하게 된다.
  5. 코드의 실행 결과는 실행 컨텍스트에서 관리된다.

실행 컨텍스트의 역할

실행 컨텍스트(Execution Context)
실행 가능한 코드를 평가하고 실행하기 위해 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역이다.

  1. 선언에 의해 생성된 모든 식별자(변수, 함수, 클래스 등)를 스코프를 구분하여 등록 하고 식별자에 바인딩된 값의 변화를 지속적으로 관리 할 수 있어야 한다.

  2. 스코프 체인을 통해 상위 스코프로 이동하며 식별자를 검색 할 수 있어야 한다.

  3. 현재 실행 중인 코드의 실행 순서를 변경(ex. 함수 호출에 의한 실행 순서 변경)할 수 있어야 하며 다시 되돌아갈 수도 있어야 한다.

실행 컨텍스트 스택

실행 컨텍스트 스택

자바스크립트는 먼저 전역 코드를 평가하여 전역 실행 컨텍스트를 생성한다. 그리고 함수가 호출되면 코드를 평가하여 함수 실행 컨텍스트를 생성하는데, 이때 생성된 실행 컨텍스트는 스택 자료 구조로 관리된다. 이를 실행 컨택스트 스택(Execution context stack) 이라고 한다.

실행 컨텍스트 스택은 코드의 실행 순서를 관리 한다. 실행 가능한 코드가 평가되면 실행 컨텍스트가 생성되고 실행 컨텍스트 스택의 최상위에 쌓인다. 실행 컨텍스트 스택의 최상위에 존재하는 실행 컨텍스트를 실행 중인 실행 컨텍스트(running execution context) 라 부른다.

동기식 처리 모델과 비동기식 처리 모델

자바 스크립트 엔진은 단 하나의 실행 컨텍스트 스택을 갖는다. 동시에 두가지 이상의 태스크를 실행할 수 없으며, 싱글스레드(single thread)로 동작한다 는 것을 의미한다.

  • 동기식 처리 모델(Synchronous processing model): 하나의 처리가 종료되어야 다음 처리를 실행할 수 있다. 직렬적으로 태스크를 수행하며, 어떤 작업이 수행중이면 다음 작업은 대기하게 된다.
  • 비동기식 처리 모델(Asynchronous processing model): 병렬적으로 태스크를 수행하며 태스크가 종료되지 않더라도 대기하지 않고 다음 태스크를 실행한다. 자바스크립트에 동시성(concurrency)을 부여하여 싱글 스레드의 약점을 보완한다.
    • 단점:
      1. 순차적으로 실행되지 않아서 가독성이 좋지 않다.
      2. 콜벡헬을 유발한다.
      3. 에러 처리가 어렵다.

렉시컬 환경 (Lexical Environment)

렉시컬 환경: 식별자가 선언되는 환경. (= 렉시컬 스코프)
객체 형태의 스코프(전역, 함수, 블록 스코프)를 만들고 이 곳에 식별자를 등록한다. 그리고 등록된 식별자에 바인딩된 값을 관리한다. 스코프를 구분하여 식별자를 등록하고 관리하는 저장소 역할.

  • 실행 컨텍스트 스택: 코드의 실행 순서를 관리
  • 렉시컬 환경: 스코프와 식별자를 관리

렉시컬 환경은 3가지 컴포넌트 로 구성되어진다.

  1. 환경 레코드(Environment Record): 스코프에 포함된 식별자를 등록하고 등록된 식별자에 바인딩된 값을 관리하는 저장소이다.

  2. 외부 렉시컬 환경에 대한 참조(Outer Lexical Environment Reference): 외부 렉시컬 환경을 가리키는 참조를 저장한다. 외부 렉시컬 환경이란 해당 실행 컨텍스트를 생성한 실행 가능한 코드를 포함하는 상위 코드의 렉시컬 환경을 말한다.

  3. this 바인딩(This binding): 렉시컬 환경의 this에 바인딩된 객체(ThisBinding)를 나타낸다.

함수 객체의 내부 슬롯 [[Environment]]
자바스크립트의 모든 함수는 함수 정의가 평가되어 함수 객체를 생성할 때, 현재 실행 중인 실행 컨텍스트의 렉시컬 환경을 함수 객체의 내부 슬롯 [[Environment]]에 저장한다. 함수 객체의 내부 슬롯 [[Environment]]이 바로 렉시컬 스코프를 구현하는 메커니즘이다.

실행 컨텍스트의 생성과 식별자 검색 과정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var x = 1;
const y = 2;

function foo (a) {
var x = 3;
const y = 4;

function bar (b) {
const z = 5;
console.log(a + b + x + y + z);
}
bar(10);
}

foo(20); // 42

1. 전역 객체 생성

2. 전역 코드 평가

  1. 전역 실행 컨텍스트 생성
  2. 전역 렉시컬 환경 생성
    1. 전역 환경 레코드 생성
    2. 1.1. 객체 환경 레코드 생성
    3. 1.2. 선언적 환경 레코드 생성
    1. 외부 렉시컬 환경에 대한 참조 할당
    1. this 바인딩

3. 전역 코드 실행

식별자를 검색할 때는 실행 중인 실행 컨텍스트의 렉시컬 환경에서 식별자를 검색한다.

4. foo 함수 코드 평가

  1. 함수 실행 컨텍스트 생성
  2. 함수 렉시컬 환경 생성
    1. 함수 환경 레코드 생성
    1. 외부 렉시컬 환경에 대한 참조 할당
    1. this 바인딩

5. foo 함수 코드 실행

6. bar 함수 코드 평가

7. bar 함수 코드 실행

8. bar 함수 코드 실행 종료

9. foo 함수 코드 실행 종료

10. 전역 코드 실행 종료

실행 컨텍스트와 블록 레벨 스코프

var 키워드로 선언한 변수
오로지 함수의 코드 블록 만을 지역 스코프로 인정하는 함수 레벨 스코프를 따른다.

let 키워드로 선언한 변수
모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 을 지역 스코프로 인정하는 블록 레벨 스코프(Block-level scope)를 따른다.


REFERENCE
https://poiemaweb.com

  • © 2020-2025 404 Not Found
  • Powered by Hexo Theme Ayer