1. 개념
실행 컨텍스트는 코드를 실행하는데 필요한 환경을 제공하고, 코드의 실행결과를 관리하는 영역이다.
즉 식별자를 등록하고 관리하는 스코프와, 코드 실행 순서를 구현한 내부 메커니즘이다.
상당히 추상적으로 와닿기 때문에, 정확히 무엇을 의미하고 어떻게 구성되는지 파악해보자.
2. JavaScript 코드의 실행 과정
JavaScript는 소스 코드를 두 개의 과정으로 나누어 처리한다.
- 소스 코드 평가
- 소스 코드 실행
소스 코드 평가
execution context(실행 컨텍스트)를 생성한다.
소스 코드의 변수 및 함수 선언문을 먼저 실행하여 execution context 내의 environment record(환경 레코드)에 등록한다.
결과적으로 소스 코드가 실행되기 전에 변수 및 함수 선언문의 정보를 파악할 수 있기 때문에, 호이스팅 현상이 발생하게 된다.
또한 소스 코드 실행 이후의 결과(변수 값 변경 등등)는 다시 환경 레코드에 저장된다.
소스 코드 실행
앞서 실행한 선언문을 제외한 소스 코드가 순차적으로 실행된다. (런타임 시작)
소스 코드 실행에 필요한 정보들은 execution context가 관리하는 스코프에 검색해서 취득한다.
3. Execution Context
3.1. 구성요소
Execution Context는 다음과 같이 구성되어 있다.
각 요소가 무엇인지 아래의 내용을 통해 살펴보자.
4. Lexical Environment
4.1. Environment Record
현재 컨텍스트와 관련된 코드의 식별자 정보와 상위 스코프에 대한 참조가 저장된다.
즉 매개변수 이름, 함수 선언문, 변수명 및 상위 스코프의 정보가 담기게 된다.
앞서 언급하였듯, '소스 코드 평가 단계'에서 Environment Record가 채워지기 때문에 JavaScript 엔진은 '소스 코드 실행 단계'에서 Environment Record에 저장된 값을 알 수 있게 되므로 이른바 호이스팅 현상이 발생한다.
4.2. this binding
컨텍스트가 생성되었을 때, 어떤 식으로 생성되었는지에 따라 this가 다르게 바인딩된다.
만약 현재의 컨텍스트가 전역 컨텍스트인경우 this는 전역 객체가 바인딩되며, 현재의 컨텍스트가 함수 컨텍스트일 경우 함수가 어떤 형태로 호출되었는지에 따라 this는 각각 다른 형태의 값이 바인딩된다.
4.3. Outer Environment Reference
현재 컨텍스트가 생성될 당시의 외부 Lexical Environment를 참조한다.
Outer Environment Reference의 존재로 인해 현재 스코프에 존재하지 않는 변수나 함수가 있을 때 상위 스코프로 넘어가 계속해서 탐색을 진행할 수 있다.
예를 들어 아래와 같은 코드가 있다고 가정해보자.
함수 bar 내부에는 변수 x가 선언되지 않았으나, 아무런 오류없이 console.log의 값이 출력되는 것을 볼 수 있다.
이는 함수 bar 내부에 변수 x를 찾을 수 없기 때문에, 함수 bar의 상위 스코프인 함수 foo에서 변수 x를 탐색했고, 이곳에서 변수 x를 발견했기 때문에, bar 함수는 foo 함수 내부에 선언된 변수 x의 할당 값 10을 참조하여 출력한 것이다.
function foo() {
const x = 10;
function bar() {
console.log(x); // 10
}
bar();
}
foo();
4.4. 구조 생각해보기
아래와 같은 코드가 있다고 가정해보자.
const x = 10;
function foo() {
const y = 20;
}
foo();
앞서 언급하였듯, JavaScript가 실행될 때 가장 먼저 코드 평가 과정이 이루어진다.
우선 전역 코드가 평가될 때 생성되는 Execution Context의 모습은 다음과 같다.
이후 전역 코드 실행 과정에서의 Execution Context의 모습은 아래와 같다.
선언문을 제외한 코드가 실행되기 때문에 할당문이 실행되어 Environment Record의 값이 갱신되며, foo 함수가 실행되어 call stack에 foo 함수가 추가된다.
call stack에 foo 함수가 추가되었기 때문에 foo 함수가 실행될 차례이며, 이에 따라 foo 함수 코드의 Execution Context가 생성된다.
foo 함수의 Execution Context가 생성되었을 당시의 외부 Lexical Environment는 전역 코드의 Lexical Environment이다.
따라서 foo 함수의 Outer Envirionment Reference는 전역 코드의 Lexical Environment를 가리키게 된다.
이후 foo 함수 코드의 실행 과정에서의 Execution Context는 아래와 같다.
Environment Record 값이 갱신된 것을 볼 수 있다.
'JavaScript' 카테고리의 다른 글
npm 배포 가이드 및 후일담 (feat. colorpia) (0) | 2024.01.08 |
---|---|
클로저 (Closure) (0) | 2024.01.01 |
var, let, const, 호이스팅, TDZ (0) | 2023.12.20 |
프로토타입(Prototype) (0) | 2023.10.07 |
옵셔널 체이닝(Optional Chaining) (1) | 2023.10.04 |