상권's
TIL 66 (렉시컬 환경) 본문
오늘은 지난 실핼 컨텍스트를 학습하며 끝에 언급했던 렉시컬 환경에 대해서 학습해보도록 하겠습니다.
렉시컬 환경은 식별자와 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 참조를 기록하는 자료구조로, 실행 컨텍스트를 구성하는 컴포넌트입니다.
쉽게 표현한다면, 렉시컬 환경은 스코프를 구분하여 식별자를 등록하고 관리하는 저장소의 역할을 합니다.
실행 컨텍스트는 LexicalEnvironment, VariableEnvironment 두 컴포넌트로 구성됩니다. 생성 초기에는 둘 다 하나의 렉시컬 환경을 참조하지만, 몇 가지 상황을 마주하면 VariableEnvironment를 위한 렉시컬 환경이 별도로 생성되는 데, 오늘은 컴포넌트 별로 구분하지 않고 렉시컬 환경으로 통일해서 간략하게 알아보겠습니다.
소스코드가 로드되면 자바스크립 엔진은 전역 코드를 평가합니다.
평가는 1. 전역 실행 컨텍스트를 생성하고,
2. 전역 렉시컬 환경 생성 -> 전역 환경 레코드 생성 -> 객체 환경 레코드, 선언적 환경 레코드 생성
-> this 바인딩
-> 외부 렉시컬 환경에 대한 참조 결정
순으로 진행이 됩니다.
여기서 렉시컬 환경은 다음과 같이 두 개의 컴포넌트로 구성되어 있습니다.
- 환경 레코드 > 스코프에 포함된 식별자를 등록하고 식별자에 바인딩된 값을 관리하는 저장소
- 외부 렉시컬 환경에 대한 참조 > 상위 스코프를 의미합니다.(해당 실행 컨텍스트를 생성한 소스코드를 포함하는 상위 코드의 렉시컬 환경) 이를 통해 스코프 체인을 구현함
먼저, 전역 실행 컨텍스트가 생성되고, 실행 컨텍스트 스택에 푸시합니다.
다음으로 전역 렉시컬 환경을 생성하고 전역 실행 컨텍스트에 바인딩합니다.
전역 렉시컬 환경의 구성 요소 중 하나인 전역 환경 레코드는 전역변수를 관리하는 전역 스코프, 전역 객체의 빌트인 전역 프로퍼티와 빌트인 전역 함수, 표준 빌트인 객체를 제공합니다.
전역 환경 레코드는 객체 환경 레코드와 선언적 환경 레코드로 구성되어 있습니다.
객체 환경 레코드는 var 키워드로 선언한 전역 변수, 함수 선언문으로 정의한 전역 함수, 빌트인 전역 프로퍼티와 빌트인 전역 함수, 표준 빌트인 객체를 관리하며, BindingObject 객체와 연결 됩니다.
전역 코드 평가 과정에서 var 키워드로 선언한 전역 변수와 함수 선언문으로 정의한 전역 함수는 전역 환경 레코드의 객체 환경 레코드에 연결된 BindingObject(전역 객체)를 통해 전역 객체의 프로퍼티와 메서드가 됩니다.
> var 키워드로 선언한 전역 변수, 함수 선언문으로 정의한 전역 함수가 전역 객체의 프로퍼티와 메서드가 되고 전역 객체를 가르키는 window 식별자 없이 전역 객체의 프로퍼티를 참조할 수 있는 매커니즘
선언적 환경 레코드는 let, const로 선언한 전역 변수를 관리합니다. 이로 인해서 전역 객체의 프로퍼티가 되지 ㅇ낳기 때문에 window.+식별자 와 같이 전역 객체의 프로퍼티로 참조할 수 없습니다.
다음으로 this 바인딩이 이루어집니다. 전역 환경 레코드의 [[GlobalThisValue]] 내부 슬롯에 this가 바인딩됩니다. 일반적으로 전역 코드에서 this는 전역 객체를 가르키므로 전역 객체가 바인딩됩니다.
마지막으로 외부 렉시컬 환경에 대한 참조 결정이 이뤄집니다.
현재 평가 중인 소스코드를 포함하는 외부 소스코드의 렉시컬 환경, 즉 상위 스코프를 가리킵니다. 이를 통해 스코프 체인을 구현합니다.
젼역 코드의 경우에는 외부 렉시컬 환경에 대한 참조에 null이 할당 됩니다. 이는 전역 렉시컬 환경이 스코프 체인의 종점에 존재함을 의미합니다.
평가 과정이 끝나면 순차적으로 코드가 실행됩니다. 변수 할당문이 실행되며 값이 할당되고 함수가 호출됩니다.
이 때 변수나 함수 이름이 선언된 식별자인지를 확인하는데, 스코프 별로 동일한 이름이 여러 개 존재할 수 있습니다. 이처럼 어느 스코프의 식별자를 참조하면 되는 지 결정하는 과정을 식별자 결정이라고 합니다. 식별자 결정은 실행 중인 실행 컨텍스트에서 식별자를 검ㅂ색하기 시작하고, 검색할 수 없다면 외부 렉시컬 환경에 대한 참조가 가르키는 상위 스코프로 이동해 식별자를 찾습니다. 이 것이 스코프 체인의 동작 원리입니다. 만약 전역 렉시컬 환경에서도 검색할 수 없는 식별자가 있다면 참조 에러가 발생합니다.
코드를 실행하는 과정에서 함수를 만나게 되면 함수 실행 컨텍스트가 생성되고 위와 같은 순서를 다시 거치게 됩니다. 이후 함수가 종료되면 해당 실행 컨텍스트는 스택에서 빠지게 됩니다.
블록 레벨 스코프의 경우에는 선언적 환경 레코드를 갖는 렉시컬 환경을 새롭게 생생하여 기존의 전역 렉시컬 환경을 교체합니다. 그리고 블록의 실행이 종료되면 이전의 렉시컬 환경으로 되돌아옵니다.
오늘은 전역 코드의 평가와 실행에 따른 렉시컬 환경에 대해서 알아보았습니다. 어느정도 자바스크립트에 대해 학습을 하신 분이시라면 조금 더 구체적인 그림을 그릴 수 있지 않을까라는 생각도 들면서 그럴 수 있길 바라고 있습니다.
이후에 시간을 내어서 이해하기 쉽도록 그림도 그려서 첨부해보고, 함수가 평가되고 실행되는 과정도 렉시컬 환경으로 설명해보도록 하겠습니다.
참고 문서 : 모던 자바스크립트 Deep Dive
'~2022 작성 글 > TIL' 카테고리의 다른 글
TIL 68 (브라우저 렌더링 과정) (0) | 2022.03.15 |
---|---|
TIL 67 (클로저) (0) | 2022.03.01 |
TIL 65 (실행 컨텍스트) (0) | 2022.02.27 |
TIL 64 (BookDam server TestCode Error) (0) | 2022.02.26 |
TIL 63 (var, let, const, 호이스팅) (0) | 2022.02.23 |