- ECMAScript 사양은 소스코드를 4가지 타입으로 구분. 4가지 타입의 소스코드는 실행 컨텍스트를 생성
- 소스코드의 타입에 따라 실행 컨텍스트르 생성하는 과정과 관리 내용이 다르기 때문
소스코드의 타입 | 설명 |
전역 코드 global code | - 전역에 존재하는 소스코드. 전역에 정의된 함수, 클래스 등의 내부 코드는 포함되지 않음 - 전역 변수를 관리하기 위해 최상위 스코프인 전역 스코프 생성 - var키워드로 선언된 전역 변수와 함수 선언문으로 정의된 전역 함수를 전역 개체의 프로퍼티와 메서드로 바인딩하고 참조하기 위해 전역 변수와 연결 - 전역 코드가 평가되면 전역 실행 컨텍스트 생성 |
함수 코드 function code | - 함수 내부에 존재하는 소스코드. 함수 내부에 중첩된 함수, 클래스 등의 내부 코드는 포함되지 않음 - 지역 스코프를 생성하고 지역변수, 매개변수, arguments 객체를 관리 - 생성한 지역 스코프를 전역 스코프에서 시작하는 스코프 체인의 일원으로 연결 - 함수 코드가 평가되면 함수 실행 컨텍스트 생성 |
eval 코드 eval code | - 빌트인 전역 함수인 eval 함수에 인수로 전달되어 실행되는 코드 - strict mode에서 자신만의 독자적인 스코프 생성 - eval코드가 평가되면 eval 컨텍스트가 생성 |
모듈 코드 module code | - 모듈 내부에 존재하는 소스코드. 모듈 내부의 함수, 클래스 등의 내부 코드는 포함되지 않음 - 모듈별로 독립적인 스코프 생성 - 모듈 코드가 평가되면 모듈 실행 컨텍스트 생성 |
소스코드의 평가와 실행
- 자바스크립트는 "소스코드의 평가"와 "소스코드의 실행" 과정으로 나누어 처리
- 소스코드의 평가: 실행 컨텍스트를 생성하고 변수, 함수 등의 선언문만 먼저 실행하여 생성된 변수나 함수 식별자를 키로 실행 컨텍스트가 관리하는 스코프 (렉시컬 환경의 환경 레코드)에 등록
- 소스코드의 실행: 선언문을 제외한 소스코드가 순차적으로 실행 (런타임). 소스코드 실행에 필요한 정보, 즉 변수나 함수의 참조를 실행 컨텍스트가 관리하는 스코프에서 검색하여 취득. 변수 값의 변경 등 소스코드의 실행 결과는 다시 실행 컨텍스트가 관리하는 스코프에 등록
실행 컨텍스트의 역할
- 실행 컨텍스트는 소스코드를 실행하는데 필요한 환경을 제공하고 실행 결과를 실제로 관리하는 영역
- 선언에 의해 생성된 모든 식별자(변수, 함수, 클래스 등)를 스코프를 구분하여 등록하고 상태 변화(식별자에 바인딩된 값의 변화)를 지속적으로 관리해야 함
- 스코프는 중첩 관계에 의해 스코프 체인을 형성해야 함. 즉 스코프 체인을 통해 상위 스코프로 이동하며 식별자를 검색할 수 있어야 함
- 현재 실행 중인 코드의 실행 순서를 변경(함수의 호출에 의한 변경 등)할 수 있어야 하며 다시 되돌아갈 수도 있어야 함
- 실행 컨텍스트는 식별자(변수, 함수, 클래스 등의 이름)를 등록하고 관리하는 스코프와 코드 실행 순서를 관리를 구현한 내부 메커니즘. 모든 코드는 실행 컨텍스트를 통해 실행되고 관리
- 식별자와 스코프: 실행 컨텍스트의 렉시컬 환경
- 코드 실행 순서: 실행 컨텍스트 스택
실행 컨텍스트 스택
- 실행 컨텍스트 스택은 코드의 실행 순서를 관리
- 실행 컨텍스트는 스택 stack 자료 구조로 관리
- 실행 중인 실행 컨텍스트 running execution context: 실행 컨텍스트 스택의 최상위에 존재하는 실행 컨텍스트. 현재 실행 중인 코드의 실행 컨텍스트
const x = 1;
function foo() {
const y = 2;
function bar() {
const z = 3;
console.log(x + y + z);
}
bar();
}
foo(); // 6
렉시컬 환경
- 렉시컬 환경 lexical environment는 식별자와 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 차몾를 기록하는 자료구조로 실행 컨텍스트르 구성하는 컴포넌트
- 렉시컬 환경은 스코프와 식별자를 관리
- 실행 컨텍스트는 LexicalEnvironment 컴포넌트와 VariableEnvironment로 구성되어 있고, 초기에는 하나의 동일한 렉시컬 환경을 참조하나, 몇 가지 상황에 달라지는 경우가 있으나 이번 정리에서는 구분하지 않음
- 렉시컬 환경은 두개의 컴포넌트로 구성
- 환경 레코드 environment record
- 스코프에 포함된 식별자를 등록하고 등록된 식별자에 바인딩된 값을 관리하는 저장소
- 환경 레코드는 소스코드의 타입에 따라 관리하는 내용에 차이가 있음
- 외부 렉시컬 환경에 대한 참조 outer lexical environment reference
- 외부 렉시컬 환경에 대한 참조는 상위 스코프를 가리킴
- 상위 스코프란 외부 렉시컬 환경, 즉 해당 실행 컨텍스트를 생성한 소스코드를 포함하는 상위 코드의 렉시컬 환경을 뜻함
- 외부 렉시컬 환경에 대한 참조를 통해 단방향 링크드 리스트인 스코프 체인을 구현
- 환경 레코드 environment record
실행 컨텍스트의 생성과 식별자 검색 과정
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); // 42
전역 객체 생성
전역 코드 평가
- 전역 실행 컨텍스트 생성
- 전역 렉시컬 환경 생성
- 전역 환경 레코드 생성
- 객체 환경 레코드 생성
- 선언적 환경 레코드 생성
- this 바인딩
- 외부 렉시컬 환경에 대한 참조 결정
- 전역 환경 레코드 생성
전역코드 실행
- 식별자 결정 indentifier resolution: 어느 스코프의 식별자를 참조하면 되는지 결정, 실행 중인 실행 컨텍스트에서 식별자 검색 시작
foo 함수 코드 평가
- 함수 실행 컨텍스트 생성
- 함수 렉시컬 환경 생성
- 함수 환경 레코드 생성
- this 바인딩
- 외부 렉시컬 환경에 대한 참조 결정
- 함수를 어디서 호출했는지가 아니라 어디에 정의했는지에 따라 상위 스코프 결정
foo 함수 코드 실행
- 식별자 결정을 위해 실행 컨텍스트의 렉시컬 환경에서 식별자를 검색하기 시작
- 만약 실행 중인 실행 컨텍스트의 렉시컬 환경에서 식별자를 검색할 수 없으면 외부 렉시컬 환경에 대한 참조가 가리키는 렉시컬 환경으로 이동하여 식별자를 검색
bar 함수 코드 평가
- foo 코드 평가와 같은 실행 컨텍스트와 렉시컬 환경의 생성 과정 진행
bar 함수 코드 실행
- console 식별자 검색
- log 메서드 검색
- 표현식 a + b + x + y + z의 평가
- 현재 실행 중인 실행 컨텍스트의 렉시컬 환경에서 시작하여 외부 렉시컬 환경에 대한 참조로 이어지는 렉시컬 환경의 연속에서 검색
- console.log 메서드 호출
bar 함수 코드 실행 종료
foo 함수 코드 실행 종료
전역 코드 실행 종료
- 실행 컨텍스트 스택에는 아무것도 남지 않게 됨
실행 컨텍스트와 블록 레벨 스코프
- let, const 키워드로 선언한 변수는 모든 코드 블록(함수, if 문, for 문, while문, try/catch 문 등)을 지역 스코프로 인정하는 블록 레벨 스코프 block-level scope를 따름
- 해당 코드 블록이 실행되면 해당 코드 블록을 위한 블록 레벨 스코프가 생성하고, 선언적 환경 레코드를 갖는 렉시컬 환경을 새롭게 생성하여 기존의 전역 렉시컬 환경을 교체
- 이 때 새롭게 생성된 코드 블록을 위한 외부 렉시컬 환경의 외부 렉시컬 환경에 대한 참조는 해당 코드 블록이 실행되기 이전의 전역 렉시컬 환경을 가리킴
- 참고: var 키워드로 선언한 변수는 오로지 함수의 코드 블록만 지역 스코프로 인정하는 함수 레벨 스코프를 따름
let x = 1;
if (true) {
let x = 10;
console.log(x); // 10
}
console.log(x); // 1
'Javascript > 모던 자바스크립트 DeepDive' 카테고리의 다른 글
[모던 자바스크립트 Deep Dive] 24 클로저 (0) | 2023.12.18 |
---|---|
[모던 자바스크립트 Deep Dive] 22 this (1) | 2023.12.17 |
[모던 자바스크립트 Deep Dive] 21 빌트인 객체 (1) | 2023.12.16 |
[모던 자바스크립트 Deep Dive] 20 strict mode (0) | 2023.12.14 |
[모던 자바스크립트 Deep Dive] 19 프로토타입 (1) | 2023.12.14 |