23.1 소스코드의 타입
- 소스코드의 타입에 따라 실행 컨텍스트를 생성하는 과정과 관리내용이 다름
1) 전역 코드
- 전역 실행 컨텍스트 생성
- 전역 변수를 관리하기 위해 최상위 스코프인 전역 스코프를 생성
- var 키워드로 선언된 전역 변수와 함수 선언문으로 정의된 전역 함수를 전역 객체의 프로퍼티와 메서드로 바인딩하고 참조하기 위해 전역 객체와 연결
2) 함수 코드
- 함수 실행 컨텍스트 생성
- 지역 스코프를 생성하고 지역 변수, 매개 변수 , arguments 객체를 관리
- 생성한 지역 스코프를 전역 스코프에서 시작하는 스코프 체인의 일원으로 연결
3) eval 코드
- eval 실행 컨텍스트 생성
- strct mode(엄격 모드)에서 자신만의 독자적인 스코프 생성
4) 모듈 코드
- 모듈 실행 컨텍스트 생성
- 모듈별로 독립적인 모듈 스코프 생성
23.2 소스코드의 평가와 실행
- 자바스크립트 엔진은 소스 코드를 1) 소스코드의 평가 2) 소스코드의 실행 과정으로 나누어 처리
ex)
var x;
x = 1;
1) 소스코드의 평가
- 변수 선언문 var x;를 먼저 실행
- 생성된 변수 식별자 x는 실행 컨텍스트가 관리하는 스코프에 등록되고 undefined로 초기화
2) 소스코드의 실행
- 변수 할당문 x=1;만 실행
- x 변수에 값을 할당하려면 먼저 x 변수가 선언된 변수인지 확인
- 실행 컨텍스트가 관리하는 스코프에 x 변수가 등록되어 있는지 확인
- 스코프에 등록되어 있다면 x 변수는 소스코드 평가 과정에서 선언문이 실행되어 등록된 변수
23.3 실행 컨텍스트의 역할
실행 컨텍스트 (execution context)
- 자바스크립트의 동작 원리를 담고 있는 핵심 개념
- 소스코드를 실행하는 데 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역
- 식별자(변수, 함수, 클래스 등의 이름)를 등록하고 관리하는 스코프와 코드 실행 순서 관리를 구현한 내부 메커니즘
- 모든 코드는 실행 컨텍스트를 통해 실행되고 관리
- 식별자와 스코프는 실행 컨텍스트의 렉시컬 환경으로 관리
- 코드 실행 순서는 실행 컨텍스트 스택으로 관리
23.4 실행 컨텍스트 스택
- 자바스크립트 엔진은 먼저 전역 코드를 평가하여 전역 실행 컨텍스트 생성
- 함수가 호출되면 함수 코드를 평가하여 함수 실행 컨텍스트 생성
const x = 1;
function foo() {
const y = 2;
function bar() {
const z = 3;
console.log(x+y+z);
}
bar();
}
foo(); //6
- 코드가 실행되는 시간의 흐름에 따라 실행 컨텍스트 스택에는 실행 컨텍스트가 추가(push)되고 제거(pop)됨
- 실행 컨텍스트 스택의 최상위에 존재하는 실행컨텍스트는 실행 중인 코드의 실행 컨텍스트
1) 전역 코드의 평가와 실행
- 전역 코드를 평가하여 전역 실행 컨텍스트를 생성하고 실행 컨텍스트 스택에 푸시
- 전역 변수 x와 전역 변수 foo는 전역 실행 컨텍스트에 등록
- 전역 코드가 실행되면 전역 변수 x에 값이 할당되고 전역 함수 foo가 호출
2) foo 함수 코드의 평가와 실행
- 전역 함수 foo가 호출되면 코드의 제어권이 foo 함수 내부로 이동
- foo 함수 내부의 함수 코드를 평가하여 foo 함수 실행 컨텍스트를 생성하고 실행 컨텍스트 스택에 푸시
- foo 함수의 지역 변수 y와 중첩 함수 bar가 foo 함수 실행 컨텍스트에 등록
3) bar 함수 코드의 평가와 실행
- 중첩 함수 bar가 호출되면 코드의 제어권인 bar 함수 내부로 이동
- bar 함수 내부의 함수 코드를 평가하여 bar 함수 실행 컨텍스트를 생성하고 실행 컨텍스트 스택에 푸시
- bar 함수 의 지역 변수 z가 bar 함수 실행 컨텍스트에 등록
- bar 함수 코드가 실행되면 지역 변수 z에 값이 할당되고 console.log 메서드를 호출한 이후 bar함수는 종료
4) foo 함수 코드로 복귀
- bar 함수가 종료되면 코드의 제어권은 다시 foo 함수로 이동
- bar 함수 실행 컨텍스트를 실행 컨텍스트 스택에서 팝하여 제거
- foo 함수 종료
5) 전역 코드로 복귀
- foo 함수가 종료되면 코드의 제어권은 다시 전역 코드로 이동
- foo 함수 실행 컨텍스트를 실행 컨텍스트 스택에서 팝하여 제거
- 전역 실행 컨텍스트도 실행 컨텍스트 스택에서 팝하여 제거
23.5 렉시컬 환경
- 식별자와 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 참조를 기록하는 자료구조로 실행 컨텍스트를 구성하는 컴포넌트
- 키와 값을 갖는 객체 형태의 스코프 (전역, 함수, 블록 스코프)를 생성하여 식별자를 키로 등록하고 식별자에 바인딩된 값을 관리
- 스코프를 구분하여 식별자를 등록하고 관리하는 저장소 역할을 하는 렉시컬 스코프의 실체
- LexicalEnvironment 컴포넌트와 VariableEnvironment 컴포넌트로 구성
1) 환경 레코드 (Environment Record)
- 스코프에 포함된 식별자를 등록하고 등록된 식별자에 바인딩된 값을 관리하는 저장소
2) 외부 렉시컬 환경에 대한 참조 (Outer Lexical Environment Reference)
- 외부 렉시컬 환경에 대한 참조는 상위 스코프를 가리킴
- 상위 스코프
-> 해당 실행 컨텍스트를 생성한 소스코드를 포함하는 상위 코드의 렉시컬 환경
- 외부 렉시컬 환경에 대한 참조를 통해 단방향 링크드 리스트인 스코프 체인을 구현
23.6 실행 컨텍스트의 생성과 식별자 검색 과정
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
23.6.1 전역 객체 생성
- 전역 객체는 전역 코드가 평가되기 이전에 생성
- 빌트인 전역 프로퍼티, 빌트인 전역 함수, 표준 빌트인 객체 추가
- 동작환경에 따라 클라이언트 사이드 Web API 또는 특정 환경을 위한 호스트 객체 포함
23.6.2 전역 코드 평가
1) 전역 실행 컨텍스트 생성
- 전역 실행 컨텍스트를 생성하여 실행 컨텍스트 스택에 푸시
2) 전역 렉시컬 환경 생성
- 전역 렉시컬 환경(Global Lexical Environment)을 생성하고 전역 실행 컨텍스트에 바인딩
2.1) 전역 환경 레코드 생성
- 전역 변수를 관리하는 전역 스콮, 전역 객체의 빌트인 전역 프로퍼티와 빌트인 전역 함수, 표준 빌트인 객체 제공
- 객체 환경 레코드와 선언적 환경 레코드로 구성
● 객체 환경 레코드(Object Envrionment Record)생성
- var 키워드로 선언한 전역 변수,
- 함수 선언 문으로 정의한 전역 함수,
- 빌트인 전역 프로퍼티와 빌트인 전역함수, 표준 빌트인 객체 관리
- BindingObject는 "전역 객체 생성"에서 생성된 전역 객체
- 전역 코드 평가 과정에서 var 키워드로 선언한 전역 변수와 함수 선언문으로 정의한 전역 함수는 전역 환경 레코드의 객체 환경 레코드에 연결된 BindingObject를 통해 객체의 프로퍼티와 메서드가 됨
- x 변수는 var 키워드로 선언한 변수
- "선언 단계"와 "초기화 단계"가 동시에 진행
- 전역 코드 평가 시점에 객체 환경 레코드에 바인딩된 BindingObject를 통해 전역 객체에 변수 식별자를 키로 등록한 다음, 암묵적으로 undefined를 바인딩 (변수 호이스팅)
● 선언적 환경 레코드(Declarative Environment Record) 생성
- let, const 키워드로 선언한 전역 변수는 선언적 환경 레코드에 등록되고 관리
- const 키워드로 선언한 변수는 "선언 단계"와 "초기화 단계"가 분리되어 진행
( 런타임에 실행 흐름이 변수 선언문에 도달하기 전까지 일시적 사각지대(TDZ)에 빠지게 됨
2.2) this 바인딩
- 전역 환경 레코드의 [[GlobalThisValue]] 내부 슬롯에 this 바인딩
- 전역 코드에서 this는 전역 객체를 가리키므로 전역 환경 레코드의 [[GlobalThisValue]] 내부 슬롯에는 전역 객체가 바인딩
- 전역 코드에서 this를 참조하면 전역 환경 레코드의 [[GlobalThisValue]] 내부 슬롯에 바인딩되어 있는 객체 반환
2.3) 외부 렉시컬 환경에 대한 참조 결정
- 전역 렉시컬 환경의 외부 렉시컬 환경에 대한 참조에 null이 할당
- 전역 렉시컬 환경이 스코프 체인의 종점에 존재함을 의미
23.6.3 전역 코드 실행
- 변수 할당문이 실행되어 전역 변수 x,y에 값이 할당
- foo 함수가 호출
- 식별자 결정 실행
23.6.4 foo 함수 코드 평가
1) 함수 실행 컨텍스트 생성
- foo 함수 실행 컨텍스트 생성
2) 함수 렉시컬 환경 생성
- foo 함수 렉시컬 환경을 생성하고 foo 함수 실행 컨텍스트에 바인딩
2.1) 함수 환경 레코드 생성
- 매개변수, arguments 객체, 함수 내부에서 선언한 지역 변수와 중첩함수를 등록하고 관리
2.2) this 바인딩
- 함수 환경 레코드의 [[ThisValue]] 내부 슬롯에 this가 바인딩
- [[ThisValue]] 내부 슬롯에 바인딩될 객체는 함수 호출 방식에 따라 결정
2.3) 외부 렉시컬 환경에 대한 참조 결정
- foo 함수 정의가 평가된 시점에 실행 중인 실행 컨텍스트의 렉시컬 환경의 참조가 할당
- 자바스크립트 엔진은 함수 정의를 평가하여 함수 객체를 생성할 때 함수의 상위 스코프를 함수 객체의 내부 슬롯 [[Environment]]에 저장
23.6.5 foo 함수 코드 실행
- 매개변수에 인수가 할당되고, 변수 할당문이 실행되어 지역 변수 x,y에 값이 할당
- 함수 bar 호출
- 식별자 결정 실행
23.6.6 bar 함수 코드 평가
- bar 함수가 호출되면 bar 함수 내부로 코드의 제어권 이동
23.6.7 bar 함수 코드 실행
- 매개변수에 인수가 할당되고, 변수 할당문이 실행되어 지역 변수 z에 값이 할당
- cosole.log(a+b+x+y+z); 실행
1) console 식별자 검색
- console 식별자를 스코프 체인에서 검색
- 식별자를 검색할 때는 언제나 현재 실행중인 실행 컨텍스트의 렉시컬 환경에서 검색하기 시작
- 전역 렉시컬 환경으로 이동하여 console 식별자를 검색
- console 식별자는 객체 환경 레코드의 BindingObejct를 통해 전역 객체에서 찾을 수 있음
2) log 메서드 검색
- console 객체에서 log 메서드를 검색
- console 객체의 프로토타입 체인을 통해 메서드를 검색
- log 메서드는 상속된 프로퍼티가 아니라 console 객체가 직접 소유하는 프로퍼티
console.hasOwnProperty('log'); //true
3) 표현식 a+b+x+y+z의 평가
- a,b,x,y,z 식별자를 검색
- a 식별자는 foo 함수 렉시컬 환경에서, b 식별자는 bar 함수 렉시컬 환경에서, x와 y 식별자는 foo 함수 렉시컬 환경에서
z 식별자는 bar 함수 렉시컬 환경에서 검색
4) console.log 메서드 호출
- 표현식 a+b+x+y+z가 평가되어 생성한 값 42를 console.log 메서드에 전달되어 호출
23.6.8 bar 함수 코드 실행 종료
- bar 함수 실행 컨텍스트가 소멸되었다 하더라도 만약 bar 함수 렉시컬 환경을 누군가 참조하고 있다면
bar 함수 렉시컬 환경은 소멸하지 않음
- foo 함수 코드 실행 종료
- 전역 코드 실행 종료
23.7 실행 컨텍스트와 블록 레벨 스코프
- let, const 키워드로 선언한 변수는 모든 코드 블록을 지역 스코프로 인정하는 블록 레벨 스코프 (block-level scope)를 따름
let x = 1;
if(true) {
let x = 10;
console.log(x); //10
}
console.log(x); //1
- for문의 변수 선언문에 let 키워드를 사용한 for문은 코드 블록이 반복해서 실행될 때마다 코드 블록을 위한 새로운 렉시컬 환경을 생성
- 함수의 상위 스코프는 for 문의 코드 블록이 반복해서 실행될 때 마다 식별자의 값을 유지해야함
- for 문의 코드 블록이 반복해서 실행될 때마다 독립적인 렉시컬 환경을 생성하여 식별자의 값을 유지
'JavaScript' 카테고리의 다른 글
[Deep dive] 25장 클래스 (1) (0) | 2023.08.15 |
---|---|
[Deep dive] 24장 클로저 (0) | 2023.08.14 |
[Deep dive] 22장 this (0) | 2023.08.11 |
[Deep dive] 21장 빌트인 객체 (0) | 2023.08.11 |
[Deep dive] 20장 strict mode (0) | 2023.08.11 |