2023년 6월 28일
이론JS
조회 : 433|2분 읽기
실행 컨텍스트
🏭 실행 컨텍스트(EC)
자바스크립트 코드가 실행되고 연산되는 범위를 나타내는 추상적인 개념.
실행할 코드에 제공할 환경 정보들을 모아놓은 객체(ECO)
아래와 같은 두 단계를 거쳐 생성된다.
1. Creation Phase
LexicalEnvironment 생성
- 변수-식별자 맵핑 구조
- 렉시컬 환경 정보가 계속 바뀜
Variable Environment 생성
- 해당 EC 안에서 변수 상태에 의해 생성된 바인딩을 보유하는 렉시컬 환경
- 렉시컬 환경 정보가 생성됐을 때 값을 유지
2. Execution Phase
변수 할당 끝나고 코드 실행
🌍 전역 실행 컨텍스트(GEC)
기본 실행 컨텍스트로 함수 내부에 없는 코드는 전역 컨텍스트에서 실행
⭐ 단 한 개만 정의되는 전역 Context
GEC의 this -> window(browser) | global(node)
JS 작동원리 Call Stack에서 제일 처음 들어가 있으며 FEC를 실행시킨다.
🔨 함수 실행 컨텍스트(FEC)
함수 실행(호출)될 때 마다 정의되고 GEC 위에 올라가 실행되는 Context
JS 작동원리의 Call Stack에서 실행되는 함수의 단위
Example
javascript1let front = 'react'; 2let back = 'spring'; 3let browser = 'chrome'; 4var appStack; 5 6function createApp(...stacks){ 7 let devops = 'aws'; 8 stacks.push(devops, browser) 9 return stacks 10} 11 12appStack = createApp(front, back);
1. Execution Phase 전 GEC의 형태
일반 코드, 변수가 작동하는 것과 같이 동작한다.
처음 초기화를 하기 전에 선언
GlobalExectionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Object",
// 식별자 바인딩
front: < uninitialized >,
back: < uninitialized >,
browser: < uninitialized >,
createApp: < func >
}
outer: <null>,
ThisBinding: <Global Object>
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Object",
// 식별자 바인딩
appStack: < uninitialized >,
}
outer: <null>,
ThisBinding: <Global Object>
}
}
2. 변수 할당이 끝난 후 GEC
선언한 변수에 값 초기화
GlobalExectionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Object",
// Identifier bindings go here
front: 'react',
back: 'spring',
browser: 'chrome',
createApp: < func >
}
outer: <null>,
ThisBinding: <Global Object>
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Object",
appStack: undefined,
}
outer: <null>,
ThisBinding: <Global Object>
}
}
3. 함수가 호출된 FEC
함수 호출했으니 함수 실행하기 위해 렉시컬이 FEC로 넘어간다.
outer(GEC)에서 외부에 참조해야하는 값이 있는지 확인한다.
여기서는 하나의 바로 GEC를 참조하기 때문에 browser(만약 node.js라면 node) 값 있는지 확인
FunctionExectionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
Arguments: {front: 'react', back: 'spring', length: 2},
},
outer: <GlobalLexicalEnvironment>,
ThisBinding: <Global Object or undefined>,
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
stack: undefined
},
outer: <GlobalLexicalEnvironment>,
ThisBinding: <Global Object or undefined>
}
}
4. 실행 단계가 된 FEC
함수 실행 끝나고 다시 GEC로 렉시컬 넘어감
FunctionExectionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
Arguments: {front: 'react', back: 'spring', length: 2},
},
outer: <GlobalLexicalEnvironment>,
ThisBinding: <Global Object or undefined>,
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
stacks: ['react', 'spring', 'aws', 'chrome']
},
outer: <GlobalLexicalEnvironment>,
ThisBinding: <Global Object or undefined>
}
}
🎨 간단한 그림
- GEC 정의
- GEC 안에 있는 FEC 정의 후 실행
- GEC 위에 올라왔던 FEC 제거
🏇 Lexical Environment
Lexical 중첩 구조를 기반으로 특정 변수 및 함수에 대한 식별자(unique)의 연결을 정의
Environment Record과 null이 될 수 있는 Lexical 외부 환경 참조로 구성
함수 정의, 블록, try-catch 등 특정 구문 구조와 연결되며 코드가 평가 완료될 때마다 새로운 Lexical Environment 생성
각 렉시컬 환경은 세가지 모듈을 가짐
🧾 Environment Record
관련 렉시컬 환경범위 내에서 생성된 식별자 바인딩을 기록
🧱 outerEnvironmentReference (외부 환경 참조)
렉시컬 환경 값들이 논리적으로 중첩돼있는 모델을 사용함
내부(현재) 렉시컬 환경을 논리적으로 감싸고 있는 렉시컬 환경(외부)의 참조
-> 내부 렉시컬에서 외부 렉시컬의 변수에 접근할 수 있게 해줌
🔏 this binding
this의 값이 결정, 설정된다.
FEC에서 this는 함수가 어떻게 호출되는지에 달렸다.
객체 참조에 의해 호출되면 this의 값은 해당 객체로 설정된다.
아니라면 전역 객체나 undefined로 설정된다.
참고