Lexical Environment(어휘적 환경) 란
- 코드가 어디서 실행되며 주변에 어떤 코드가 있는지 대체적인 정보를 담고 있는 환경
- 함수 본인 내부의 식별자, 식별자에 바인딩 된 값 등을 기록하고 있는 하나의 자료구조
- 이러한 Lexical Environment가 모여서 코드의 문맥을 구성한다.
Lexical Environment의 구성 요소
- Environment Record (환경 레코드)
- 변수와 함수 선언을 저장
- ex) 함수 내부의 변수와 함수 선언이 저장 - Outer Environment Reference (외부 환경 참조)
- 상위 lexical environment 가리킴
- 이를 통해 함수가 중첩되어 있을 때 내부 함수가 외부 함수의 변수와 함수에 접근 가능
Execution Context(실행 컨텍스트) 란
- 자바스크립트에서 코드가 실행되는 환경을 의미한다.
- 모든 코드는 실행 컨텍스트에서 평가되고 실행된다.
- 자바스크립트 엔진은 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 객체를 구성하고, 이를 콜 스택에 쌓아 올렸다가, 가장 위에 쌓여 있는 컨텍스트와 관련 있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장한다.
Execution Context의 구성 요소
- Variable Environment
현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보다. 선언 시점의 Lexical Environment의 스냅샷으로, 식별자의 변경 사항은 반영되지 않는다. - Lexical Environment
처음에는 Variable Environment와 같지만 식별자의 변경 사항이 실시간으로 반영된다. - This Binding
this 식별자가 바라봐야 할 대상 객체를 의미한다.
Execution Context 예시
다음과 같은 코드가 있다고 가정하자
const globalVar = 'global';
function outerFunction() {
let outerVar = 'outer';
function innerFunction() {
let innerVar = 'inner';
console.log(globalVar); // 'global'
console.log(outerVar); // 'outer'
console.log(innerVar); // 'inner'
}
innerFunction();
}
outerFunction();
위 코드에 대해서 각각의 Execution Context 정보는 다음과 같이 생성된다.
Execution Context (Global)
---------------------------
Variable Environment:
globalVar: 'global'
outerFunction: <function>
Lexical Environment:
Environment Record(환경 레코드):
globalVar: 'global'
outerFunction: <function>
Outer Environment Reference(외부 환경 참조): null
this Binding:
Global Object (e.g., window in browsers)
Execution Context (outerFunction)
---------------------------
Variable Environment:
outerVar: 'outer'
innerFunction: <function>
Lexical Environment:
Environment Record(환경 레코드):
outerVar: 'outer'
innerFunction: <function>
Outer Environment Reference(외부 환경 참조): Global Lexical Environment
this Binding:
undefined (strict mode일 경우) 또는 Global Object (non-strict mode)
Execution Context (innerFunction)
---------------------------
Variable Environment:
innerVar: 'inner'
Lexical Environment:
Environment Record(환경 레코드):
innerVar: 'inner'
Outer Environment Reference(외부 환경 참조): Outer Function Lexical Environment
this Binding:
undefined (strict mode일 경우) 또는 Global Object (non-strict mode)
Execution Context (실행 컨텍스트) 의 실행 단계
실행 컨텍스트는 다음과 같이 두 단계를 거쳐서 만들어진다.
- 생성 단계(Creation phase) - 변수의 '선언'을 읽는다
- Lexical Environment 구성
- Environment Record (환경 레코드) 생성
- 현재 실행 컨텍스트 내에서 사용되는 변수, 함수 선언을 기록
- var로 선언된 변수는 undefined로 초기화되고, let과 const로 선언된 변수는 초기화되지 않은 상태로 남는다.
- 함수 선언(function) 전체가 메모리에 로드 됨
- Outer Environment Reference (외부 환경 참조)
- 현재 실행 컨텍스트가 참조하는 외부 Lexical Environment를 가리킨다.
- Variable Environment 구성
- this 바인딩 결정
- 실행 컨텍스트가 생성될 때 this가 가리키는 객체를 결정
- 전역 컨텍스트의 경우 this는 전역 객체를 가리킨다 (브라우저에서는 window 객체) - 실행 단계(Execution phase) - 변수의 '값'을 읽는다.
- 변수 값 할당
- var로 선언된 변수에 실제 값이 할당된다.
- let과 const로 선언된 변수는 TDZ(Temporal Dead Zone)에서 벗어난 후 값이 할당된다.
- 코드 실행
- 코드가 순차적으로 실행되며, 함수 호출 및 변수 할당이 이루어진다.
- 각 변수와 함수는 해당 실행 컨텍스트의 Lexical Environment에서 값을 읽고 쓴다.
아래와 같은 코드가 있을 때 실행 컨텍스트는 다음과 같은 순서라 작동한다.
var temp = 'test';
function b (){
console.log('hello world');
}
function a (){
b();
}
a();
* 처음 자바스크립트 코드를 실행하는 순간 첫번째 그림처럼 Global Execution Context(전역 컨텍스트)가 콜 스택에 담긴다. 브라우저 환경에서 window 객체를 사용할 수 있는 이유가 이것 때문이다.
- 콜 스택엔 전역 컨텍스트를 제외하곤 다른 컨텍스트가 없기에 전역 컨텍스트와 관련된 코드를 진행한다.
- 전역 컨텍스트와 관련된 코드를 진행 중 a함수를 실행하였기에 a 함수의 환경 정보들을 수집하여 a 실행 컨텍스트를 생성, 콜 스택에 담는다.
콜 스택 최상단에 a 실행 컨텍스트가 있기에 기존의 전역 컨텍스트와 관련된 코드의 실행을 일시적으로 중단한 후 a 실행 컨텍스트의 코드를 실행한다. - a 함수 내부에서 b 함수를 실행하였기에 b 함수의 환경 정보들을 수집, 실행 컨텍스트를 생성, 콜 스택에 담는다.
이전과 똑같이 콜 스택 최상단에 b 실행 컨텍스트가 있기에 기존 a 실행 컨텍스트와 관련된 코드의 실행을 일시적 중단한다. - b 함수가 종료된 후 b 실행 컨텍스트가 콜 스택에서 제거된다.
제거 후 콜 스택 최상단에는 a 실행 컨텍스트가 있기에 이전에 중단된 지점부터 코드 진행이 재개된다. - a 함수 또한 종료된 후 실행 컨텍스트가 콜 스택에서 제거된다.
이후엔 전역 공간에 실행할 코드가 남아있지 않다면 콜 스택에서 전역 컨텍스트 또한 제거되며 콜 스택에 아무것도 남지 않은 상태로 종료된다.
'Javascript' 카테고리의 다른 글
Scope와 Closure (1) | 2024.07.30 |
---|