Javascript 실행 컨텍스트

fgStudy·2022년 4월 14일
0

자바스크립트

목록 보기
9/26
post-thumbnail

소스코드 평가와 실행

자바스크립트는 어떻게 변수를 선언하고 값을 등록할까?

아래 var 키워드로 등록한 변수 x가 있다.

var x;
var x = 1;

이 변수는 다음과 같은 과정으로 변수를 생성한다.

  1. 자바스크립트는 변수, 함수 등 선언문을 런타임 이전에 식별자를 등록한다. 즉 평가과정에서 var 스코프를 등록한다.

  2. 그리고 실행과정(런타임)때 변수 할당문 x=1만 실행하며 값을 바인딩한다. 이 때 먼저 변수 x가 해당 스코프에 등록된 변수인지를 확인해야 한다. 만약 등록된 변수라면 값을 바인딩한다. 그리고 바인딩한 결과실행 컨텍스트에 등록해서 관리를 한다.


자바스크립트 엔진은 우리가 작성한 소스코드를 2개의 과정으로 나누어서 처리한다.

소스코드 평가(var x)
소스코드 실행(x = 1)

평가 과정: var x

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

실행 과정: x = 1

  • 평가과정이 끝나면 선언문을 제외한 소스코드 실행하면서 실행컨텍스트 스코프에서 변수, 함수 참조
  • 변수 값 변경 등의 실행 결과는 다시 실행 컨텍스트가 관리하는 스코프에 등록한다.

그리고 이 과정을 관리하는 것이 바로 실행 컨텍스트이다.


실행 컨텍스트

실행 컨텍스트 역할

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

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

각각의 실행컨텍스트는 하나의 메모리 섹션이다. 

그 섹션은 변수, 함수를 저장(렉시컬 환경의 환경 레코드)하거나 다른 섹션을 참조(외부 렉시컬 환경에 대한 참조)할 수 있다. 실행 컨텍스트는 코드가 실행되면서 추가(push)되고 제거(pop)되는데 이것이 바로 실행컨텍스트의 스택이다.


실행 컨텍스트 스택

예제를 통해 살펴보면서 실행 컨텍스트 스택에 대해 설명하겠다.

const x = 1;
function foo() {
  const y = 2;
  function bar() {
    const z = 3;
    console.log(x + y + z);
  }
  bar();
}

foo();

위의 코드의 실행 컨텍스트의 스택은 아래와 같이 표현할 수 있다.

해당 코드는 ① 전역코드 평가/실행 → ② foo 함수 코드 평가 실행 → ③ bar 함수 코드 평가와 실행(foo함수 일시중단) → ④ foo 함수 복귀 → ⑤ 전역코드로 복귀로 이루어져있다. 코드 실행과정을 보면서 실행 컨텍스트 스택이 어떤식으로 작동push/pop하는지 확인해보자.

해당 코드를 간략히 설명하겠다.

  1. foo함수는 전역에서 foo()를 통해 호출되면, 전역코드 실행은 중단되고 코드 제어권이 foo함수 내부로 이동한다.

  2. 자바스크립트 엔진은 foo함수 내부의 함수코드를 평가하여 foo함수 실행컨텍스트를 생성하고 스택에 푸시한다. 이때 실행컨텍스트에 foo 함수의 지역변수 y와 중첩함수 bar(함수 내부가 평가되는 것이 아닌, 그저 함수 객체를 등록하는 것)가 등록된다.

  3. 그리고 아래 bar()를 통해 중첩함수 bar가 호출하면서 제어권이 bar함수 내부로 이동하며넛 함수 코드 평가가 이루어지고 foo 함수 실행은 일시중단된다.

  4. bar함수가 종료되어 스택에서 pop되면 foo로 돌아가는데 foo로 돌아가면 더이상 실행할 코드가 없으므로 이 함수도 pop된다. 그러면 이제 다시 전역으로 돌아가는데

  5. 전역에서도 더이상 실행할 코드가 없으므로 pop되며 종료된다.


이처럼 실행 컨텍스트 스택은 코드의 실행순서를 관리한다.
그림을 보면 알듯이, 실행 컨텍스트 스택의 최상위에 존재하는 실행 컨텍스트는 현재 실행되는 코드의 실행컨텍스트이다. 이를 실행중인 실행 컨텍스트(running execution context)이라 칭한다.


렉시컬 환경

렉시컬 환경은 식별자와 식별자에 바인딩된 값(환경 레코드), 상위 스코프에 대한 참조(외부 렉시컬 환경에 대한 참조)를 기록하는 자료구조로,실행 컨텍스트를 구성하는 컴포넌트이다. 

예시로 해당 코드의 렉시컬 환경을 살펴보자.

const x = 1;

function foo() {
  const y = 2;
  console.log(x+y);
}

위의 그림을 보면 foo 렉시컬 환경은 식별자 y와 y에 바인딩된 값이 있다. 그리고 foo 렉시컬 스코프는 상위 스코프인 global 렉시컬 환경을 참조하고 있다.

이처럼 렉시컬 환경은 키와 값을 갖는 객체 형태의 스코프를 생성하여 식별자를 키로 등록하고 식별자에 바인딩된 값을 관리한다. 즉 렉시컬 환경은 식별자를 등록하고 관리하는 저장소 역할을 하는 렉시컬 스코프의 실체다.

렉시컬 스코프에 대한 자세한 설명은 링크를 참고해주시길 바란다.


렉시컬환경은 환경 레코드와 외부 렉시컬 환경에 대한 참조 2개의 컴포넌트로 구성된다.

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

  2. 외부렉시컬 환경에 대한 참조 : 상위 스코프를 가르킨다. 이 때 상위 스코프란 외부 렉시컬 환경, 즉 해당 실행 컨텍스트를 생성한 소스코드를 포함하는 상위 코드의 렉시컬 환경을 말한다. 이를 통해 단방향 링크드 리스트 스코프 체인을 구현한다.

profile
지식은 누가 origin인지 중요하지 않다.

0개의 댓글