실행 컨텍스트란?
실행할 코드에 제공할 환경 정보들을 모아놓은 객체
자바스크립트가 어떤 실행 컨텍스트가 활성화되는 시점에 하는 일
- 선언된 변수를 위로 끌어올리구요 = 호이스팅(hoisting)
- 외부 환경 정보를 구성하구요.
- this 값을 설정해요.
콜 스택(call stack)
실행 컨텍스트 즉, 동일 환경에 있는 코드를 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고
이것을 ‘스택’의 한 종류인 콜스택에 쌓아올립니다.
가장 위에 쌓여있는 컨텍스트와 관련된 코드를 실행하는 방법으로 코드의 환경 및 순서를 보장할 수 있어요.
실행 컨텍스트의 구성방법
- 전역공간
- eval()함수
- 함수(우리가 흔히 실행컨텍스트를 구성하는 방법)
// ---- 1번
var a = 1;
function outer() {
function inner() {
console.log('test1',a); //undefined
var a = 3; //선언부 var a;가 inner()펑션 제일 상단으로 올라가고, 여기는 a=3이 되면서 위의 console.log()의 a는 undefined가 됨. 만약 현재 줄이 없었더라면 1이 나왔을 것
}
inner(); // ---- 2번
console.log('test2',a); //1
}
outer(); // ---- 3번
console.log('test3',a); //1
코드실행 → 전역(in) → 전역(중단) + outer(in) → outer(중단) + inner(in) → inner(out) + outer(재개) → outer(out) + 전역(재개) → 전역(out) → 코드종료
결국은 특정 실행 컨텍스트가 생성되는(또는 활성화되는) 시점이 콜 스택의 맨 위에 쌓이는(노출되는) 순간을 의미
실행 컨텍스트 객체의 구성 정보
- VariableEnvironment
1. environmentRecord(=record)
- 현재 컨텍스트 내의 식별자 정보들이 저장됨. var a = 3의 경우, var a를 의미
- 함수에 지정된 매개변수 식별자, 함수자체, var로 선언된 변수 식별자 등
2. outerEnvironmentReference(=outer) : 외부 환경 정보를 갖고있어요.
3. 선언 시점 LexicalEnvironment의 snapshot - LexicalEnvironment
VariableEnvironment와 동일하지만, 스냅샷을 유지하지 않고 변경사항을 실시간으로 반영(‘environmentRecord’와 ‘outerEnvironmentReference’로 구성).
실행 컨텍스트를 생성할 때, VE에 정보를 먼저 담은 다음, 이를 그대로 복사해서 LE를 만들고 이후에는 주로 LE를 활용. - ThisBinding
this 식별자가 바라봐야할 객체
호이스팅
LE(LexicalEnvironment)의 구성요소 중 record(=environmentRecord)의 수집 과정이 hoisting
- 매개변수 및 변수는 선언부를 호이스팅
- 함수 선언은 전체를 호이스팅(함수 표현식은 선언부만 호이스팅)
그렇기 때문에 협업을 많이 하고, 복잡한 코드일 수록. 전역 공간에서 이루어지는 코드 협업일 수록 함수 표현식을 활용하는 습관을 들이도록 합시다!!
// 함수 선언문은 전체를 hoisting
function sum (a, b) { // 함수 선언문 sum
return a + b;
}
// 변수는 선언부만 hoisting
var multiply;
console.log(sum(1, 2));
console.log(multiply(3, 4));
multiply = function (a, b) { // 변수의 할당부는 원래 자리
return a + b;
};
스코프, 스코프 체인
각각의 실행 컨텍스트는 LE 안에 record와 outer를 가지고 있고, outer 안에는 그 실행 컨텍스트가 선언될 당시의 LE정보가 다 들어있으니 scope chain에 의해 상위 컨텍스트의 record를 읽어올 수 있다.
- outer : LE(LexicalEnvironment)의 구성요소 중 outer(=outerEnvironmentReference)는 스코프 체인이 가능토록 하는 것(외부 환경의 참조정보)라고 할 수 있어요
- 스코프 : 식별자에 대한 유효 범위
- 스코프 체인 : 식별자의 유효 범위를 안에서 부터 바깥으로 차례로 검색해나가는 것
outer는 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조.
예) A함수 내부에 B함수 선언 → B함수 내부에 C함수 선언(Linked List)한 경우 어떻게 될까요?
결국 타고, 타고 올라가다 보면 전역 컨텍스트의 LexicalEnvironment를 참조하게 됩니다.
항상 outer는 오직 자신이 선언된 시점의 LexicalEnvironment를 참조하고 있으므로, 가장 가까운 요소부터 차례대로 접근 가능
결론 : 무조건 스코프 체인 상에서 가장 먼저 발견된 식별자에게만 접근이 가능
var a = 1;
var outer = function() {
var inner = function() {
console.log(a); // undefined
var a = 3;
};
inner();
console.log(a); // 1
};
outer();
console.log(a); // 1
'JavaScript' 카테고리의 다른 글
콜백 함수 (0) | 2023.05.28 |
---|---|
this 바인딩 - call, apply, bind (0) | 2023.05.25 |
깊은 복사 (0) | 2023.05.25 |
Map, Set (0) | 2023.05.24 |
ES6에서 추가된 문법과 기능 (0) | 2023.05.24 |