Javascript 동작 원리 (3) - Lexical Environment
이번 글에서는 이전에 깊게 다루지 못했던 Execution Context의 Lexical Environment에 대해 좀 더 파헤쳐보려 한다.
Execution Context In depth
Execution Context는 생성 단계에서 아래 3가지 구성요소를 만든다.
ExecutionContext = {
ThisBinding: <this value>,
VariableEnvironment: { ... },
LexicalEnvironment: { ... }
}1) ThisBinding
this는 현재 실행 중인 코드가 어떤 객체의 맥락에서 동작하는지를 가리키는 키워드다. 이 값은 함수의 호출방식에 따라 달라지며, ThisBinding에 저장된다.
- 일반 함수 호출: 전역 객체 (strict mode: undefined)
- 메서드 호출: 호출한 객체
- 생성자 호출 (new): 새로 생성된 인스턴스
- call / apply / bind: 명시적으로 지정한 객체
단, 화살표 함수는 자체 ThisBinding 없이 선언 시점 외부 스코프의 this를 사용한다. 이는 뒤에서 다룰 Lexical Scoping과 같은 원리다.
2) VariableEnvironment
이전 글에서 생성 단계에서 var 선언은 undefined로 초기화되고, 함수 선언문은 함수 객체 자체가 적재된다고 했다.
이 처리가 이뤄지는 공간이 바로 Variable Environment 이다.
Variable Environment는 Execution Context 생성 시점의 초기 상태를 그대로 유지하는 것이 특징이다. 코드가 실행되면서 블록 스코프 등에 의해 환경이 변할 수 있는데, Variable Environment는 그 변화와 무관하게 처음 상태를 보존한다.
3) LexicalEnvironment
이번 글에서 집중적으로 다룰 대상이다.
JavaScript에서 스코프는 함수가 호출된 위치가 아니라 정의된 위치(코드가 작성된 위치)를 기준으로 결정된다.
이를 Lexical Scoping(렉시컬 스코핑)이라 부른다.
Lexical Environment는 이 규칙을 엔진 내부에서 구현하는 모델로, 식별자(변수/함수 이름)와 그 값을 연결하고 스코프 체인을 관리한다. Variable Environment가 생성 시점의 초기 상태를 유지하는 반면, Lexical Environment는 실행 중 블록스코프(let/const) 진입 등에 따라 동적으로 변한다.
Lexical Environment의 구조
Lexical Environment를 좀 더 자세히 들여다보자. Lexical Environment는 아래 두가지 구성요소로 이뤄진다.
1) Environment Record
실제로 식별자와 값을 연결하고 저장하는 "저장소" 역할이다. 성격에 따라 두 종류로 나뉜다.
Declarative Environment Record: 함수 내부(혹은 블록 스코프)의 let, const, 매개변수, 함수 선언 등을 관리한다.Object Environment Record: 전역 컨텍스트처럼 전역 객체와 연결되는 바인딩을 관리할 때 등장한다.
참고: 실행 환경(브라우저/Node)과 모드(strict mode 여부), ES 버전에 따라 체감 동작이 조금씩 달라 보일 수 있으므로 "개념모델"로 이해하는 것이 좋다.
2) Reference to Outer Lexical Environment
현재 Lexical Environment가 자신을 감싸는 외부 스코프를 가리키는 참조다. 이 참조들이 연쇄적으로 연결되면서 Scope Chain(스코프 체인)이 만들어진다.
덕분에 내부 스코프에서 외부 스코프의 변수를 찾을 수 있다.
- 현재 스코프에서 찾는다
- 없으면 outer 참조를 타고 올라간다
- 전역까지 올라가도 없으면 ReferenceError
그리고 이 구조가 그대로 Closure(클로저) 와 연결된다.
클로저는 함수가 선언될 당시의 outer Lexical Environment를 기억해두고, 나중에 실행될 때도 그 환경을 계속 참조할 수 있게 해준다.
즉, 함수 실행이 끝나도 참조가 살아있다면, 엔진은 그 환경을 GC로 정리하지 못한다.
출처
https://www.webdevlog.com/p/how-js-works-lexical-environment/
http://dmitrysoshnikov.com/ecmascript/es5-chapter-3-1-lexical-environments-common-theory/
Written on
2024-09-09 14:32
