실행 문맥 / 맥락 / 환경
자바스크립트의 컨텍스트를 나누는 기준은 4가지가 있습니다.
- 전역컨텍스트
- 자바스크립트 실행과 동시에 생성되고, 모든 코드 블럭의 배경이되는 컨텍스트, 모든 코드 실행 후 마지막으로 종료
- 함수컨텍스트
- 함수가 실행될 때 컨텍스트 생성, 함수 종료 후 컨텍스트 종료
- eval
- 문제를 발생시킬 수 있기 때문에 자주 사용하지 않습니다.
- module
- import 되는 순간에 컨텍스트가 생성되고 모듈 코드가 끝났을 때 컨텍스트 종료
위와 같이 4종류로 나누어 보았는데요. 사실 자바스크립트의 컨텍스트는 대부분이 함수컨텍스트입니다.
현재 실행환경과 관련된 식별자 정보
컨텍스트가 실행되면 만들어지는 환경정보 두가지와 ThisBiding이 있습니다.
- VariableEnvironment - 식별자 정보 수집
- environmentRecord (snapshot)
- outerEnvironmentReference (snapshot)
특징 : 컨텍스트 내부의 변수의 값들이 변화가 생기면 실시간 반영 X
- LexicalEnvironment - 각 식별자의 '데이터' 추적
- environmentRecord - 환경 기록
- outerEnvieonmentReference - 외부 환경 참조
특징 : 컨텍스트 내부의 변수의 값들이 변화가 생기면 실시간 반영 O
ThisBinding은 다음 포스팅에 다루어 보겠습니다.
특별한 경우를 제외하고는 렉시컬환경 ( 렉시컬스코프 ) 위주로 살펴보아도 문제가되지 않습니다
어떠한 실행컨텍스트의 환경정보를 작성해둔 사전
LexicalEnvironment의 모양새
내부식별자 a : 현재의 값
내부식별자 b : 현재의 값
외부 정보 : d를 참조한다
실행컨텍스트의 현재 정보 ( 내부적, 외부적 ) 를 나타내줍니다.
EnvironmentRecord는 현재 문맥의 식별자 정보를 수집합니다.
실행컨텍스트가 생성되면 가장 먼저 하는 과정으로 이 과정에서 일어나는 일을 "호이스팅"이라는 단어로 사용하자 라고 약속되어 있습니다.
호이스팅이란 실제하는 현상은 아니고 위 과정을 좀 더 쉽게 이해하기위해 만든 허구의 단어
console.log (a());
console.log (b());
console.log (c());
function a() { return 'a'; }
const b = function bb() { return 'bb'; }
const c = function () { return 'c'; }
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
function a() { return 'a'; }
const b;
const c;
console.log (a());
console.log (b());
console.log (c());
b = function bb() { return 'bb'; }
c = function () { return 'c'; }
위 과정은 environmentRecord에 식별자 정보를 수집하는 과정입니다. 여러분들이 일반적으로 알고있는 호이스팅의 개념과 같죠?
여기서의 '환경'은 Lexical Environment 입니다. 즉 외부의 렉시컬 환경을 참조하는 겁니다.
outerEnvironmetReference가 관여하는것이 바로 스코프체인 ( scope chain ) 입니다. 스코프체인은 외부의 렉시컬환경 참조에의해 발생하는 것입니다.
함수의 특징 중 한가지는, 외부에서 내부를 참조할 수 없고 내부에서 외부만 참조가 가능합니다. 그 이유가 바로 이 외부환경 참조 때문인겁니다^^.
const test2 = () => {
const var1 = 'var1';
}
test2();
console.log(var1); // Uncaught ReferenceError: var1 is not defined
위와 같이 외부에서 내부를 참조하려할 때 에러를 뿜어내게 되는데 이게 바로 내부에서 외부환경만 참조할 수 있다는 뜻입니다.
그렇다면 변수의 유효범위 ( 스코프 ) 는 누가 만들어주는 걸까요?? 정답은 실행컨텍스트입니다.
정확히 파고들어 보자면 실행컨텍스트 내부에 렉시컬환경에 환경기록과 외부환경참조 라는 녀석들이 만들어주는것이죠.
환경기록은 실행컨텍스트 내부에 식별자를 수집한다고 했고, 외부환경참조는 실행컨텍스트 부모의 렉시컬환경을 참조한다고 했습니다.
여기서 일어나는 현상을 스코프 체인이라고 했었고, 이러한 현상으로 체인방식으로 모든 실행컨텍스트는 부모에서 부모로 참조할 수 있는것입니다!