자바스크립트의 만능 가제트, 실행 컨텍스트가 무엇일까?

Eamon·2021년 8월 11일
7

JavaScript

목록 보기
8/8

이 글은 모던 자바스크립트 Deep Dive 23장 실행 컨텍스트 부분을 보고 공부한 것을 정리한 글입니다.

우선, 우리는 이 글을 읽고나서 자바스크립트의 실행컨텍스트가 도대체 무엇을 하는 애인지 알게될 것이다. 그리고 생각보다 이 아이는 자바스크립트 엔진 내에서 다양한 일을 하고있다는 것도 알게 될것이다.



JS 실행 컨텍스트를 이해하면 설명할 수 있는 것들

  1. 스코프를 기반으로 식별자와 식별자에 바인딩 된값을 관리하는 방식
  2. 호이스팅이 발생하는이유
  3. 클로저의 동작 방식
  4. 태스크 큐 와 함께 동작하는 이벤트 핸들러의 비동기 처리 동작 방식

위의 네 가지를 실행 컨텍스트로 설명할 수있는데 다르게 말하면 네가지가 일어나는 일 중심에 실행 컨텍스트가 큰 일을 하고있다고도 이해할수있다.


그래서 이 분이 떠올랐다지... 만능 실행 컨텍스트 형사...

🔍 자바스크립트는 우선 소스코드(실행 가능한 코드)를 4가지타입으로 분류한다.

→ 4가지인 이유는 소스코드 타입에 따라 실행 컨텍스트를 생성하는 과정과 관리 내용이 다르다

  1. 전역 코드
    • 전역 스코프 생성 var 키워드로 선언된 전역 변수와 함수 선언문으로 정의된 전역 함수를 전역 객체의 프로퍼티와 메서드로 바인딩하고 참조하기 위해 전역 객체와 연결 되어야한다.
    • 전역 코드가 평가 되면 전역 실행 컨텍스트가 생성된다.
  2. 함수 코드
    • 지역 스코프 생성 매개변수 arguments 객체를 관리해야한다. 생성한 지역 스코프전역스코프에서 시작하는 스코프 체인의 일원으로 연결해야한다.
    • 함수코드가 평가되면 함수 실행 컨텍스트 가 생성 된다.
  3. eval 코드
    • strict mode 에서 자신만의 독자적인 스코프를 생성
    • eval 코드가 평가되면 eval 실행 컨텍스트 생성
  4. 모듈 코드
    • 모듈 코드는 모듈별로 독립적인 모듈 스코프를 생성한다.
    • 모듈 코드가 평가되면 모듈 실행 컨텍스트 생성



📗 소스코드의 처리과정

모든 소스코드는 평가 과정실행 과정으로 나누어 처리한다.

평가 과정에서는

  • 실행 컨텍스트를 생성
  • 변수 함수등의 선언문 먼저 실행 생성된 변수나 함수 식별자를 키로 실행 컨텍스트가 관리하는 스코프(렉시컬 환경의 환경레코드)에 등록한다.

실행과정에서는

  • 소스에 필요한 정보 들을 스코프에서 검색해서 얻거나 값을 할당한다.

🔍 자 아래 예제를 자바스크립트 코드가 어떤 순서로 평가하고 실행하는지 생각해보자.

const x=1; // 전연변수 선언

// 함수 정의
function foo () {
const x = 10; // 지역 변수 선언

console.log(a+ x);
}

foo(100) // 함수 호출

console.log(x) // 메서드 호출

1. 전역 코드 평가

  • 전역 코드의 선언문만 먼저 실행한다.

    • 변수선언문과 함수 선언문이 먼저 실행된다.

      const x;
      function foo () {
      const x = 10; // 지역 변수 선언
      
      console.log(a+ x);
      }
      
    • 생성된 전역변수와 전역함수가 실행컨텍스트가 관리하는 전역스코프(렉시컬 환경의 환경레코드) 에 저장한다.

    • 또 전역 변수와 함수 선언문으로 정의된 전역 함수는 전역 객체의 프로퍼티와 메서드가 된다.

2. 전역 코드 실행

  • 평가가 끝나면 런타임이 시작되어 전역 코드가 순차적으로 실행된다.
x = 1 할당
foo(100) // 함수 호출 되면 함수 내부로 진입 -> 함수 평가
  • 변수에 값이 할당 되고 함수가 호출된다.
  • 함수가 호출되면 전역 코드의 실행을일시 중단하고 코드 실행 순서를 변경하여함수 내부`로 진입한다.

3. 함수 코드 평가

  • 호출하면 코드를 평가함
  • 매개변수와 지역변수 선언문 먼저 실행
  • 생성된 매개변수와 지역변수가 실행 컨텍스트가 관리하는 지역스코프에 등록된다.
  • 매개변수와 arguments 객체 지역 스코프에 등록 this 바인딩 결정

4. 함수 코드 실행

  • 런타임 시작 함수 코드 순차적으로 실행

  • 매개변수와 지역변수에 값이 할당된다

  • console.log 메소드가 호출된다.

    • 호출하기 위해서는 먼저 식별자인 console 을 스코프 체인을 통해서 검색한다.
    • console 식별자는 스코프 체인에 등록되어 있지않고 전역객체의 프로퍼티에 존재한다. 전역 객체의 프로퍼티가 마치 전역 변수 처럼 전역 스코프를 통해 검색 가능해야한다는 것을 의미한다.
  • 이처럼 코드가 실행되려면 스코프 식별자 코드 실행 순서 등의 관리가 필요하다.

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

    2. 스코프는 중첩관계에 의해 스코프 체인을 형성해야한다.

    3. 현재 실행중인 코드의 실행 순서를 변경 할수있어햐한다.

      이 모든 것을 관리하는 것이 실행 컨텍스트
      6

실행 컨텍스트 스택(=call stack)

const x=1; // 전연변수 선언

// 함수 정의
function foo () {
const x = 10; // 지역 변수 선언

console.log(a+ x);
}

foo(100) // 함수 호출

위에서 예시를 들었던 코드로 다시 실행컨텍스트가 실행컨텍스트 스택에 어떤 순서로 쌓이는지 설명을 해보면,


1. 전역 코드 평가 실행

  • 전역코드를 평가하여 실행 컨텍스트를 생성하고 실행 컨텍스트를 스텍에 푸시한다.
  • 전역 변수 x 와 함수 foo 가 전역 실행 컨텍스트의 렉시컬 환경에 저장된다.
  • 전역 코드가 실행되면 변수 x 에 값이 할당되고 foo 가 호출된다.

  1. foo 함수 코드 평가화 실행
  • foo 가 실행되면 전역 코드의 실행은 일시 중지되고 제어권은 foo 함수 내부로 이동한다.

  • foo 함수의 실행컨텍스트를 생성하고 컨텍스트스택에 푸시한다.

  • 이후 지역변수 x 와 console.log() 함수를 호출한다.

  • console.log() 함수의 실행 컨텍스트가 생성되고 스택에 푸시된다.

  • console.log() 함수가 종료된 후 스택에서 pop() 되고 다시 제어권이 foo 에게 돌아오고 foo는 더이상 코드가 없어 종료된다.

  1. 전역 코드로 복귀
  • foo 코드가 종료되면 제어권은 전역코드로 이동한다. 더이상 실행할 전역 코드가 남아있지 않으므로 전역 실행 컨텍스트도 스택에서 팝되어 스택에는 아무것도 남아있지 않게된다.

렉시컬 환경

  • 렉시컬 환경은 식별자와 식별자에 바인딩 된 값 그리고 상위스코프에 대한 참조를 기록하는 자료구조.

  • 렉시컬 환경은 환경 레코드(EnvironmentRocord)와 외부렉시컬에 대한 참조(outer lexical Enviorment Ref)두개의 컴포넌트로 구성이된다.

  1. 환경레코드
  • 스코프에 포함된 식별자를 등록하고 등록된 식별자에 바인딩된 값을 관리하는 저장소.
  1. 외부 렉시컬에 대한 참조
  • 상위 스코프를 가리킨다.


📚 정리

  • 실행 컨텍스트는 소스코드를 실행하는데 필요한 환경을 제공하고(렉시컬 환경) 코드의 실행 결과를 실제로 관리하는(실행 컨텍스트 스택 ) 영역!

  • 실행 컨텍스트는 식별자를 등록하고 관리하는 스코프(렉시컬 환경)와 코드 실행 순서를 관리(실행 컨텍스트 스택) 를 구현한 내부 매커니즘.

다음에는 실행 컨텍스트의 렉시컬 환경과 실행 컨텍스트 스텍에 대해서 좀 더 깊게 알아보려고한다.

profile
Steadily , Daily, Academically, Socially semi-nerd Front Engineer.

1개의 댓글

아주 깔끔하게 정리해주셨네요 잘 보고 갑니다~~

답글 달기