실행 컨텍스트

Eye0n·2021년 4월 28일
0

javascript

목록 보기
5/7
post-custom-banner

실행 컨텍스트는 자바스크립트의 동작 원리를 담고 있는 핵심 개념이다.

자바스크립트가 스코프를 기반으로 식별자와 식별자에 바인딩된 값을 관리하는 방식과 호이스팅이 발생하는 이유, 클로저의 동작 방식 그리고 태스크 큐와 함께 동작하는 이벤트 핸들러와 비동기 처리의 동작 방식을 이해할 수 있다.

ECMAScript사양은 소스코드를 4가지 타입으로 구분한다. 4가지 타입의 소스코드는 실행 컨텍스트를 생성한다.

1. 전역코드 : 전역에 존재하는 소스코드. 전역에 정의된 함수 클래스 등의 내부 코드는 포함 x

2. 함수코드 : 함수 내부에 존재하는 소스코드. 중첩된 함수와 클래스등의 내부 코드 포함 x

3. eval코드 : 빌트인 전역 함수인 eval함수에 인수로 전달되어 실행되는 소스코드

4. 모듈코드 : 모듈 내부에 존재하는 소스코드. 모듈 내부의 함수, 클래스 등의 내부 코드 포함 x

>  내부 코드에 대한 실행 컨택스트가 따로 생긴다.

소스코드 평가와 실행

자바스크립트 엔진은 소스코드를 평가실행 과정으로 반복 처리한다.

전역 코드 평가
전역 코드 실행
함수 코드 평가
함수 코드 실행
전역 코드로 복귀

코드 평가

실행 컨텍스트가 생성되고 변수, 함수, 클래스 등의 선언문이 평가되어 그 결과(식별자)가 생성된 실행 컨텍스트에 등록된다.

코드 실행

선언문을 제외한 코드가 순차적으로 실행된다. 이때 코드 실행에 필요한 정보를 실행 컨텍스트에서 취하고, 그 코드의 실행 결과(값 할당) 를 실행 컨텍스트에 등록하여 관리된다.

실행 컨텍스트

실행 컨텍스트는 식별자를 등록하고 관리하는 스코프코드 실행 순서 관리를 구현한
내부 메커니즘으로, 모든 코드는 실행 컨텍스트를 통해 실행되고 관리된다.

즉, 실행 컨텍스트는 소스코드를 실행하는데 필요한 정보환경을 제공하고 해당 코드의 결과를 관리한다.

정보와 환경

  • 변수 : 전역변수, 지역변수, 매개변수, 객체의 프로퍼티
  • 함수 선언
  • 변수의 유효범위(Scope)
  • this

식별자와 스코프는 실행 컨텍스트의 렉시컬 환경으로 관리하고
코드 실행 순서는 실행 컨텍스트 스택으로 관리한다.

코드 평가되면 실행 컨텍스트가 생성되고 순차적으로 실행 컨텍스트 스택 에 쌓인다
(스택에 push된 실행 컨택스트).

해당 실행 컨텍스트가 실행되어 완료되면 스택에서 사라진다.
(스택에서 pop된 실행컨택스트)

var a; // 1번 

function foo() { // 2번
  function bar() { // 3번
  }
  bar(); // 5번
} // 6번 foo함수 실행되어 완료된 시점

foo(); // 4번

실행 컨텍스트 스택에서의 push & pop된 EC

해설:

선언문에 대한 코드 평가로 인한 
1번 전역 실행 컨텍스트를 생성 후 스택에 push.
2번 foo함수 실행 컨텍스트가 생성
3번 bar함수 실행 컨텍스트가 생성

이제 순차적으로 코드를 실행
4번 foo함수가 호출되어 생성된 foo함수 EC가 스택에 push되어 실행.
5번 중첩함수인 bar함수가 실행되어 bar함수 EC가 스택에 push되고 완료 후에 스택에서 pop. 
6번 foo함수도 완료되어 스탣에서pop. 마지막에는 전역 실행 컨텍스트만이 남게된다.

실행 컨텍스트 구성요소

1. Lexical Environment
2. Variable Environment

초기에 실행 컨텍스트에선 렉시컬환경과 변수환경은 하나의 동일한 렉시컬환경을 참조한다.
이후 상황에 따라 변수환경을 위한 새로운 렉시컬 환경을 생성하고 이로인해 서로 다른 렉시컬 환경을 참조하게 된다.

렉시컬 환경


렉시컬 환경식별자식별자에 바인딩된 값, 상위 스코프에대한 참조를 기록하는 자료구조로 실행 컨택스트 구성 요소이다.(식별자와 스코프를 관리하는 자료구조)

키와 값을 갖는 객체형태의 스코프를 생성하여 식별자를 키로 등록하고 식별자에 바인딩된 값을 관리한다.

렉시컬 환경 구성 요소:

  • 환경 레코드:
    스코프에 포함된 식별자를 등록, 등록된 식별자 바인딩 값 관리 저장소

  • 외부 렉시컬 환경에 대한 참조:
    상위 스코프를 가리킴, 이때 상위 스코프는 외부 렉시컬 환경,
    즉 해당 실행 컨텍스트가 생성한 소스코드를 포함하는 상위 코드의 렉시컬 환경을 말함.

this바인딩은 전역 환경 레코드와 함수 환경 레코드에만 존재한다.

환경 레코드

Environment Record
스코프에 포함된 식별자를 등록, 등록된 식별자 바인딩 값 관리 저장소.

전역 환경 레코드: 객체 환경 레코드선언적 환경 레코드인 2개의 컴포넌트와 GlobalThisValue 내부슬롯로 구성된다.

  • Object Environment Record :
    var로 선언된 전역 변수와 함수 선언문으로 정의한 전역 함수,
    빌트인 전역 프로퍼티, 빌드인 전역 함수, 표준 빌트인 객체를 관리

  • Declarative Environment Record :
    let, const로 선언된 전역 변수를 관리

  • ThisValue :
    (Global) this바인딩값을 가리키는 환경 레코드의 내부 슬롯

함수 환경 레코드: 함수 환경 레코드 컴포넌트와 ThisValue내부슬롯으로 구성된다.

  • Functional Environment Record :
    매개변수, arguments객체, 함수 내부 지역 변수와 중첩함수 등을 등록하고 관리

  • ThisValue내부슬롯 :
    this바인딩값을 가리키는 환경 레코드 내부 슬롯.
    함수 호출 방식에 따라 this값이 정해진다.

외부 렉시컬 환경에 대한 참조

Outer Lexical Environment Reference
상위 스코프를 가리킴, 이때 상위 스코프는 외부 렉시컬 환경이다.
즉 해당 실행 컨텍스트가 생성한 소스코드를 포함하는 상위 코드의 렉시컬 환경을 말함.

실행 컨택스트 생성 순서

전역 코드 평가

전역 코드 평가

1.전역 실행 컨텍스트 생성
2.전역 렉시컬 환경 생성
2.1 전역 환경 레코드 생성
2.1.1 객체 환경 레코드 생성
2.1.2 선언적 환경 레코드 생성
2.2 this 바인딩
2.3 외부 렉시컬 환경에 대한 참조 생성

함수 코드 평가

함수 렉시컬 생성

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

다음은 아래 소스에 대한 실행 컨택스트를 이미지화한 것이다.

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);

전역 코드 평가
전역 코드 평가

전역 코드 실행
전역 코드 실행

함수 평가로인한 함수 렉시컬 생성
함수 렉시컬 생성

스택에 push된 함수 렉시컬
스택에 push된 함수 렉시컬

함수 코드 실행
함수 코드 실행

함수가 완료되어 함수 실행 컨텍스트가 스택에서 pop됨
함수 실행 컨텍스트가 스택에서 pop됨

함수가 완료되어 스택에서 함수 실행 컨텍스트가 pop되어 제거되지만, 함수 렉시컬 환경까지 소멸되는건 아니다. 함수 렉시컬 환경도 하나의 독립적인 객체로서 누군가에 의해 참조가 되지 않을 때 비로소 가비지 컬렉터에 의해 메모리 공간의 확보가 해제되어 소멸된다.

즉, 누군가가 참조를 하고 있는 경우 렉시컬 환경 객체는 소멸되지 않고 참조 대상이 된다.
이러한 현상을 클로저라 부르는데 다음에 살펴보자.

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

let, const, if, while, for 여러 등등 블록 레벨 스코프를 갖는 실행 컨텍스트는
선언적 환경 레코드를 갖는 렉시컬 환경을 새롭게 생성하여 기존의 렉시컬 환경을 교체한다.

아래 소스로 설명하자면,

let x =1;

if(true) {
  let x = 10;
  console.log(x); // 10
}

console.log(x); // 1

if문에대한 블록 스코프 렉시컬 환경 객체를 생성하여 기존 전역 렉시컬 환경을 교체한다.
이때 새롭게 생성된 블록 렉시컬 환경의 외부 렉시컬 환경에 대한 참조는 if문이 실행되기 이전의 전역 렉시컬 환경이다.

if문 블록 스코프 렉시컬 환경 객체 생성

if문이 종료되면 기존 전역 렉시컬 환경을 다시 가리킴
if문이 종료되면 기존 렉시컬 환경을 다시 가리킴


reference

모던 자바스크립트 deep dive
mdn

post-custom-banner

0개의 댓글