Skip to content

23. 실행 컨텍스트

DD edited this page Aug 7, 2021 · 2 revisions

실행 컨텍스트

소스코드를 싱행하는 데 필요한 환경을 제공하고, 코드 실행 결과를 실제로 관리하는 영역

식별자를 등록하고 관리하는 스코프 / 코드 실행 순서 관리를 구현한 내부 매커니즘.

모든 코드는 실행 컨텍스트를 통해 실행되고 관리된다

  • 식별자, 스코프는 실행 컨텍스트의 렉시컬 환경으로 관리

코드 실행 순서는 실행 컨텍스트 스택으로 관리

실행 컨텍스트를 기반으로

  • 스코프 기반 식별자와 식별자에 바인딩된 값을 관리하는 방식

  • 호이스팅이 발생하는 이유

  • 클로저의 동작 방식

  • 태스크 큐와 함께 동작하는 이벤트 핸들러/ 비동기 처리 동작 방식

를 설명할 수 있어야한다

소스코드 타입

  • 전역 / 함수 / eval / 모듈. 이 4가지에 따라 실행 컨텍스트를 생성하는 과정, 관리 내용이 다르다

  • 각 코드가 평가되면 해당 컨텍스트가 생성된다

전역코드

  • 전역 변수 관리를 위한 최상위 전역 스코프 생성

  • var로 선언된 전역 변수, 함수 선언문으로 정의된 전역 함수를 전역 객체의 프로퍼티/메서드로 바인딩

함수 코드

  • 지역 스코프 생성

  • 지역 변수, 매개변수, arguments 객체 관리

  • 생성한 지역 스코프를 전역 스코프의 스코프 체인에 연결

eval 코드

  • strict mode에서만 자신만의 독자적 스코프 생성

모듈 코드

  • 모듈벌 독립적 스코프 생성



소스코드 평가/실행

평가

  • 실행 컨텍스트 생성

  • 변수, 함수 등 선언문만 먼저 실행해서 생성된 변수/함수 식별자를 키로 실행컨텍스트가 관리하는 스코프에 등록

  • 함수 평가 과정에서 this 바인딩이 결정된다

실행

  • 평가가 끝나면 선언문을 제외한 소스코드를 순차적으로 실행(런타임)

  • 이 때 소스코드 실행에 필요한 정보(변수, 함수의 참조)를 실행컨텍스트가 관리하는 스코프에서 취득

  • 변경 사항이 생기는 실행 결과는 다시 실행컨텍스트가 관리하는 스코프에 등록




코드가 실행되려면 스코프, 식별자, 코드 실행 순서 등의 관리가 필요하다

  1. 스코프를 구분하여 식별자와 바인딩된 값이 관리되어야 함
  2. 중첩 관계에 의한 스코프 체인으로 식별자를 검색할 수 있어야 함
  3. 전역 객체의 프로퍼티도 전역 변수처럼 검색되어야 함(프로토타입 체인)
  4. 함수 호출이 종료되면 호출 이전으로 돌아가기 위해 현재 실행 중인 코드 / 이전 실행중인 코드를 구분, 관리해야 함



실행 컨텍스트 스택

  • 전역/함수 소스코드가 평가되어 실행 컨텍스트가 생성될 때 실행 컨텍스트 스택에 해당 컨테스트를 쌓는다

  • 평가 후 코드가 실행될 때 함수를 호출하게 되면 함수 코드 평가하고 함수 실행 컨텍스트를 생성해서 실행 컨텍스트 스택에 쌓는다. 이때 코드의 제어권이 함수 내부로 이동한다

  • 함수가 호출될 때마다 반복하고, 함수 호출이 끝나면 코드의 제어권을 밖으로 반환하면서 해당 함수 실행 컨텍스트도 실행 컨텍스트 스택에서 빠져나온다.

  • 실행 컨텍스트 스택의 최상위에 있는 컨텍스트를 실행 컨텍스트라고 한다. 현재 실행 중인 코드의 컨텍스트이다.




렉시컬 환경

식별자, 식별자에 바인딩된 값, 상위 스코프에 대한 참조를 기록하는 자료구조이자 실행 컨텍스트를 구성하는 컴포넌트

  • 키(식별자)-값(바인딩된 값)을 갖는 객체 형태

  • LexicalEnvironment / VariableEnvironment로 구분되어 있지만 이 책에서는 렉시컬 환경으로 통일해서 설명한다.

  • 환경 레코드 / 외부 렉시컬 환경에 대한 참조로 구성되어있다.

환경 레코드(Environment Record)

스코프에 포함된 식별자를 등록하고 바인딩된 값을 관리하는 저장소

  • 소스코드 타입에 따라 관리하는 내용에 차이 있음

외부 렉시컬 환경에 대한 참조(Outer Lexical Environment Reference)

상위 스코프(상위 코드의 렉시컬 환경)에 대한 참조

  • 즉 이 실행 컨텍스트를 생성한 외부 환경에 대한 참조

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

  1. 전역 객체 생성

  2. 전역 소스코드 평가

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

객체/선언적 환경 레코드

  • ES6 이전에는 전역 객체가 전역 환경 레코드 역할을 했지만 let, const가 등장하면서 상황이 바뀌었다.

  • let, const는 전역 객체 프로퍼티가 아닌 개념적 블록 내에 존재한다

  • 객체 환경 레코드는 var 전역 변수 / 함수 선언문 / 빌트인 전역 프로퍼티, 함수 / 표준 빌트인 객체 관리

  • 선언적 환경 레코드는 let, const로 선언한 전역 변수 관리

  • 이 두가지가 협력해서 전역 객체 관리




식별자 결정

어느 스코프의 식별자를 참고하면 되는지 결정하는 것. 식별자는 스코프만 다르다면 같은 이름을 가질 수 있다.

  • 식별자는 실행 컨텍스트의, 렉시컬 환경의, 환경 레코드에 등록되어 있다.



클로저

  • 해당 실행 컨텍스트가 실행 컨텍스트 스택에서 제거되었다고해서 렉시컬 환경까지 즉시 소멸하는 것은 아니다

  • 렉시컬 환경은 실행 컨텍스트가 참조하고 있을 뿐인 독립적인 객체이다. 따라서 렉시컬 환경(객체)를 어느 누구도 참조하고 있지 않아야 가비키 컬렉팅의 대상이 된다.

  • 다른 곳에서 해당 렉시컬 환경을 참조하고 있다면 해당 렉시컬 환경은 사라지지 않는다




블록 레벨 스코프

  • 블록 레벨 스코프를 생성하는 블록(if, for.. )은 코드 블록을 위한 새로운 렉시컬 환경을 생성한다.

  • 외부 렉시컬 환경에 대한 참조는 해당 블록문이 실행되기 이전 렉시컬 환경을 가르킨다




다시 한 번, 아래 질문에 대해 실행 컨텍스트를 기반으로 설명할 수 있는가??

  • 스코프 기반 식별자와 식별자에 바인딩된 값을 관리하는 방식

  • 호이스팅이 발생하는 이유

  • 클로저의 동작 방식

  • 태스크 큐와 함께 동작하는 이벤트 핸들러/ 비동기 처리 동작 방식