반응형
- 실행 컨텍스트의 개념을 이해하면 자바스크립트의 전반적인 이론들을 이해할 수 있다.
- 꼭 완벽 이해해보자..!
23.1 소스코드의 타입
- 소스코드에 따라 실행 컨텍스트를 생성하는 과정이 다 다르다.
- 코드가 평가될 때, 실행 컨텍스트를 생성한다.
- 전역 코드
- 전역 스코프 생성
- 전역 변수 관리
- 함수 코드
- 지역 스코프 생성
- 지역 변수, 매개변수, 인수 관리
- 스코프 체인을 연결해야한다.
- eval 코드
- 자신만의 실행 컨텍스트 생성
- 이거 사용하지 말자.
- 모듈 코드
- 독립적인 모듈 스코프 생성
24.2 소스코드의 평가와 실행
- 평가 과정에서 실행 컨텍스트를 생성하고, 식별자를 키로 실행 컨텍스트가 관리하는 스코프에 등록
- 스코프 : 렉시컬 환경의 환경 레코드
- 평가가 끝나면 런타임이 시작되고, 실행에 필요한 정보들을 실행 컨텍스트가 관리하는 스코프에서 검색하여 취득한다. 값 변경도 실행 컨텍스트에서 관리된다.
23.3 실행 컨텍스트의 역할
- 전역 변수의 평가 → 실행 컨텍스트(전역 스코프 등록) → 런타임 시작 → 함수 호출 → 함수 내부 평가 → 실행 컨텍스트(지역 스코프 등록) → 함수 내부 런타임 실행 → 함수 호출 끝 → 이전에 실행하던 곳에서 다시 시작
- 코드가 동작하기 위하여 코드를 평가하는 과정에서 먼저 식별자와 값을 수집하고, 실행 때 필요한 정보들을 스코프 체인을 기반으로 관리하여 내어주거나 수정해주며 실행하다가 평가 후 재실행을 하게 될 시 어디서부터 재시작해야되는지 등을 기억해준다.
- 프로그램이 실행될 수 있도록 조력자 역할을 톡톡히 한다!
23.4 실행 컨텍스트 스택
- stack 자료구조로 관리된다.
- 자바스크립트 배열 프로토타입 메서드의 push() , pop() 의 개념
- 전역 실행 컨텍스트가 stack의 가장 아래에 깔리고, 함수 호출 순서에 따라 stack이 push되며, 해당 실행컨텍스트에서 더이상 할일이 없을 때, 실행 컨텍스트가 pop되어 stack 에서 사라진다.
- 즉, 최상위 존재하는 실행 컨텍스트는 현재 실행 중인 코드의 실행 컨텍스트이다!
23.5 렉시컬 환경
- 스코프와 식별자를 관리. 참조를 기록하는 자료구조
- 실행 중 변수를 만나면 해당 변수를 스코프 체인에 따라 탐색해주고, 값이 존재하면 내어줌.
- 렉시컬 환경은 두 가지의 컴포넌트로 존재한다.
- 환경 레코드
- 스코프에 포함된 식별자를 등록하고 식별자에 바인딩된 값을 관리하며 타입에 따라 관리한다.
- 외부 렉시컬 환경에 대한 참조
- 상위 스코프를 참조. 해당 실행 컨텍스트에서 찾을 수 없는 식별자를 상위 스코프로 올라가며 탐색하며 스코프 체인을 구현한다.
- 환경 레코드
23.6 실행 컨텍스트의 생성과 식별자 검색 과정
23.6.1 전역 객체 생성
- 전역 코드가 평가되기전 전역 객체가 먼저 생성된다.
- 빌트인 객체, 호스트 객체 등이 생성된다.
23.6.2 전역 코드 평가
- 전역 코드 평가에 대한 순서는 아래와 같다.
- 전역 실행 컨텍스트 생성
- 전역 렉시컬 환경 생성
- 전역 환경 레코드 생성
- 객체 환경 레코드 생성
- 선언적 환경 레코드 생성
- this 바인딩
- 외부 렉시컬 환경에 대한 참조 결정
- 전역 환경 레코드 생성
1. 전역 실행 컨텍스트 생성
- 전역 실행 컨텍스트를 stack에 push
2. 전역 렉시컬 환경 생성
- 전역 렉시컬 환경을 전역 실행 컨텍스트에 바인딩한다.
2-1. 전역 렉시컬 환경 생성
- 전역 스코프, 전역 객체의 빌트인 프로퍼티와 함수, 표준 빌트인 객체 제공
- 전역 환경 레코드
- 객체 환경 레코드
- var 키워드로 선언한 전역 변수, 함수 선언문, 빌트인 전역 프로퍼티와 함수, 표준 빌트인 객체
- 위의 객체와 변수들은 BindingObject 를 통해 전역 객체의 프로퍼티와 메서드가 된다.
- 변수 호이스팅은 코드 평가 시점에서 undefined 로 초기화되고, 함수 호이스팅은 생성된 함수 객체로 즉시 할당한다.
- 선언적 환경 레코드
- let , const 로 선언한 전역 변수
- 두 키워드 또한 호이스팅이 일어나지만 일시적 사각지대(TDZ)현상으로 인해 변수 선언문 이전에 참조할 수 없다.
- 객체 환경 레코드
2-2. this 바인딩
- 전역 환경 레코드의 [[GlobalThisValue]] 내부 슬롯에 this가 바인딩 된다.
- 일반적으로 전역 코드에서 this는 전역 객체이다.
2-3. 외부 렉시컬 환경에 대한 참조
- 단방향 링크드 스코프 체인을 구현한다.
- 전역 코드일 경우 외부 렉시컬 환경에는 null이 할당된다.
- 전역 코드의 상위 스코프는 없기 때문.
23.6.3 전역 코드 실행
- 전역 변수에 값이 할당되고, 함수가 호출된다.
- 사용할 변수의 식별자가 선언되어 어느 스코프의 식별자를 참조하면 되는지를 결정하는 단계가 필요하다.
- 식별자 검색이 이뤄지고, 현재 실행중인 실행 컨텍스트를 시작으로 검색이 이뤄진다.
- 만약 현재 실행중인 실행 컨텍스트에서 해당 식별자를 찾을 수 없다면 외부 렉시컬 환경에 대한 참조가 일어난다.
23.6.4 전역 함수 코드 평가
- 함수가 호출되면 현재 평가 중인 코드의 실행을 중단한다.
- 함수 내부 코드로 제어권이 이동하며 함수 코드 평가를 시작한다.
- 함수 코드의 평가 순서는 아래와 같다.
- 함수 실행 컨텍스트 생성
- 함수 렉시컬 환경 생성
- 함수 환경 레코드 생성
- this 바인딩
- 외부 렉시컬 환경에 대한 참조 결정
1. 전역 함수 실행 컨텍스트 생성
- 해당 함수 실행 컨텍스트를 stack에 push한다.
2**. 전역 함수 렉시컬 환경 생성**
- 함수 렉시컬 환경을 해당 실행 컨텍스트에 바인딩한다.
2-1. 전역 함수 환경 레코드 생성
- 매개변수, arguments 객체, 함수 내부 선언된 지역 변수, 중첩 함수를 등록하고 관리
2-2. this 바인딩
- 함수 환경 레코드의 [[ThisValue]] 내부 슬롯에 this가 바인딩 된다.
- 호출 방식에 따라 this에 바인딩되는 객체가 달라질 것이다.
- 일반 함수의 경우 this 는 전역 객체
2-3. 외부 렉시컬 환경에 대한 참조 결정
- 함수가 전역에서 정의되었다면 외부 렉시컬 환경은 전역 렉시컬 환경의 참조가 할당된다.
- 자바스크립트는 렉시컬 스코프를 따르기 때문에 함수가 정의된 스코프에서 상위 스코프를 결정한다.
- 이 때, 함수의 상위 스코프를 함수 객체의 내부 슬롯 [[Environment]]에 저장한다.
- 이는 렉시컬 스코프를 구현하는 메커니즘
- 클로저를 이해할 수 있는 단서!!!
23.6.5 전역 함수 코드 실행
- 인수 할당과 변수 할당문이 실행되어 지역 변수에 값이 할당된다.
- 식별자를 결정하기 위해 렉시컬 환경에서 식별차를 검색하고, 없다면 외부 렉시컬 환경에 대한 참조가 가리키는 렉시컬 환경으로 이동할 것이다.
- 중첩 함수가 호출된다.
23.6.6 중첩 함수 코드 평가
- 중첩 함수가 호출되는 순간 해당 중첩 함수 내부로 코드의 제어권이 이동한다. 그리고 평가를 시작한다.
- 해당 함수 실행 컨텍스트를 stack에 push한다.
23.6.7 중첩 함수 코드 실행
- 지역 변수에 인수가 할당된다.
1. console 식별자 검색
- console 식별자를 현재 실행 중인 실행 컨텍스트에서 검색한다.
- 찾지 못했다면 외부 렉시컬 환경에 대한 참조가 가리키는 상위 함수에서 검색하고, 거기에도 없다면 상위 함수의 외부 렉시컬 환경에 대한 참조가 가리키는 상위 렉시컬 환경으로 이동한다.
2. log 메서드 검색
- console 객체의 프로토타입 체인을 통해 메서드를 검색한다.
console.hasOwnProperty('log'); // true
2. a + b + x + y + z 의 평가
- 표현식을 평가하기 위해 실행 중인 컨텍스트에서 부터 외부 렉시컬환경에 대한 참조로 이어지며 계속 검색해 간다.
3. console.log 메서드 호출
- 평가한 표현식을 console.log 메서드에 전달하여 호출 !!
23.6.8 중첩 함수 코드 실행 종료
- 실행 컨텍스트 stack 에서 중첩 함수에 대한 실행 컨텍스트를 pop!
- 스택에서는 제거되었지만 해당 함수의 렉시컬 환경까지 소멸되지 않고, 아무에게도 참조되지 않을 때, 가비지 컬렉터가 주워간다.
23.6.9 전역 함수 코드 실행 종료
- 실행 컨텍스트 stack 에서 전역 함수에 대한 실행 컨텍스트를 pop!
23.6.10 전역 코드 실행 종료
- 실행 컨텍스트 stack에서 전역 코드에 대한 실행 컨텍스트를 pop!
- 전역 코드 실행 컨텍스트가 스택에서 사라지면 실행 컨텍스트 스택에는 아무것도 남지 않는다.
23.7 실행 컨텍스트와 블록 레벨 스코프
- if 문의 코드블록이 실행되면 해당 블록을 위한 블록 레벨 스코프를 생성하고, 이를 위해 선언적 환경 레코드를 갖는 렉시컬 환경을 새롭게 생성하여 기존 전역 렉시컬 환경을 교체한다.
- 실행 컨텍스트를 생성하는게 아닌 블록 레벨의 렉시컬 환경을 생성하는 것이다.
- 그리고 해당 렉시컬 환경에서 찾을 수 없는 식별자가 생기면 외부 렉시컬 환경에 의한 참조를 구현한다.
- for 문의 경우 반복문이 실행될 때마다 값을 유지하고 있어야하기 때문에 선언적 환경 레코드를 갖는 렉시컬 환경에서 식별자의 값을 유지한다.
- 실행 컨텍스트를 생성하는게 아닌 블록 레벨의 렉시컬 환경을 생성하는 것이다.
728x90
반응형
'개발서적 > 모던 자바스크립트 Deep Dive' 카테고리의 다른 글
클래스 (모던 자바스크립트 Deep Dive) (0) | 2024.04.17 |
---|---|
클로저 (모던 자바스크립트 Deep Dive) (0) | 2024.04.16 |
this (모던 자바스크립트 Deep Dive) (0) | 2024.04.16 |
빌트인 객체 (모던 자바스크립트 Deep Dive) (0) | 2024.04.16 |
strict mode (모던 자바스크립트 Deep Dive) (0) | 2024.04.16 |