실행할 코드에 제공할 조건과 환경 정보들(현재 환경과 관련된 식별자 정보)을 모아놓은 객체.
실행컨텍스트가 활성화될 시점에 선언된 변수를 끌어올리고(호이스팅), 환경정보 설정과 this가 설정되는 등의 동작이 일어남.
동일한 환경에 있는 코드들을 실행할때 필요한 정보를 모아서 컨텍스트를 구성하여 이를 콜 스택에 올리고, 가장위에 있는 컨텍스트와 관련 코드를 먼저 실행하는 식으로 진행이 됨(스택과 똑같은 개념 FILO).
실행컨텍스트 구성 방법은 전역공간, eval()함수, 함수,블록({})(ES6)등이 있으며, 일반적인 실행컨텍스트 구성은 함수를 실행하는 방법뿐임.
var a = 1;
function outer(){
function inner(){
console.log(a);
var a = 3;
}
inner();
console.log(a);
}
outer();
console.log(a);
콜스택 순서
1 . 자바스크립트를 실행시키는 순간, 빈 콜스택에 전역 컨텍스트가 담김.
2 . 순차적으로 진행이 되다가outer()함수가 호출되면, 콜스택에outer실행 컨텍스트가 쌓임.
3 .outer함수 내부코드가 실행하하다가inner()함수가 호출되면, 콜스택에inner실행 컨텍스트가 쌓임.
4 .inner함수 내부코드 실행이 끝나면, 콜스택에inner()의 실행 컨텍스트가 콜 스택에서 제거.
5 .inner함수 실행 컨텍스트가 제거가 되고, 콘솔출력까지 끝나면, 콜스택에outer()의 실행 컨텍스트가 콜 스택에서 제거.
6 . 콜 스택에 남은 전역 컨텍스트에 있는 콘솔 출력까지 끝나면, 콜 스택에 전역 컨텍스트가 제거되면서, 콜 스택에는 아무것도 없는상태로 종료.
- VariableEnvironment
현재 컨텍스트 내의 식별자들에 대한 정보(environmentRecord) + 외부 환경 정보(outerEnvironmentReference) 를 말하며 LexicalEnvironment의 스냅샷으로 변경되지 않음.
- LexicalEnvironment
VariableEnvironment와 같은정보가 최초로 들어가지만, 변경사항이 실시간으로 반영되는 정보.
- ThisBinding
this 식별자가 바라봐야 할 대상 객체
한국어 번역으로 '어휘적 환경','정적 환경'이라는 단어로 많이 해석.
여기서 사용자는사전적인이라는 표현이 더 어울린다고 언급함.
예를 들어 "컨텍스트 내부에 a,b,c같은 식별자들이 있고 외부 정보는 d를 참조하도록 구성되어있다" 이런식으로 컨텍스트를 구성하는 환경정보가 있는 사전처럼 구성했다로 이해.(인프런 코어 자바스크립트 강의 참고)
1.함수에 지정된 매개변수 식별자
2.선언한 함수가 있을경우 함수 그 자체 정보.
3.var로 선언된 변수의 식별자
자바 스크립트 엔진이 소스 코드의 environmentRecord 정보를 수집. 코드를 실행하기전에는 해당 환경의 코드 식별자들을 전부 알고있는 상황. 이 때, 자바스크립트 엔진은 실행컨텍스트 실행 시, 모든 식별자 정보를 알기때문에, 실행하는 소스코드 상 아래에 있는 실행컨텍스트가 실행이 가능하다. 이 때, 식별자 정보는 실제로 실행컨텍스트 맨위로 끌어올려지지않지만 편의상 끌어 올리는 것으로 간주. 즉 Hoisting이 발생.
function a(){
console.log(func());
function func(){
return 1000;
}
var x = 1;
console.log(x);
var x;
console.log(x);
var x = 2;
console.log(x);
}
a();
위 소스 코드에서 a함수를 실행하면 콜스택에 a 함수에 관련된 실행 컨텍스트가 실행. 이 때, 식별자 정보는 가상의 Hoisting 현상에 의해 a 함수 내부 위로 끌어올려져서, 아래와 같은 소스로 실행이 됨.
function a(){
function func(){
return 1000;
}
console.log(func());
var x;
var x;
var x;
x = 1;
console.log(x);
console.log(x);
x = 2;
console.log(x);
}
a();
1.
func함수 선언
2.func함수 실행 결과값 출력
3.변수x를 선언.
4.아래에도 식별자x를 선언하지만, 이미 할당 되어있기때문에 무시.
5.변수x에 데이터1를 할당.
6.11,12번째줄에는 할당된 변수x의 데이터 값 출력.(1)
7.14번째줄에는 할당된 변수x에 데이터 2를 할당.
8.15번째줄에 할당된 변수x의 데이터 값 출력.(2)
9.a함수의 컨텍스트가 종료되서 콜 스택에서 제거. 그 다음 전역컨텍스트도 종료되어 콜 스택에서 제거
처음에는 undefined,1,undefined,2순서로 출력이 되는줄 알았지만, 이전에 공부했었던 DataType의 식별자 할당하는 방법을 생각하면 이미 식별자 x가 할당이 되어있기때문에, 아래에 할당외어있는 두번째에 재선언은 무시한다고 생각 하면 될꺼 같다.
function 정의부만 존재. 함수명 자체가 곧 변수명.(필수)Scope는 식별자에 대한 유효범위.
let,const는 블록 범위)outerEnvironmentReference: 현재 호출된 함수가 선언될 당시의 외부 환경(LexicalEnvironment)를 참조.
스코프 체인: 식별자의 유효범위 안에서 바깥으로 차례로 검색해 나가는것을 말함.
var a = 1;
var outer = function(){
var inner = function(){
console.log(a);
}
inner();
}
outer();
a변수값을 찾는과정
1.inner함수의LexicalEnvironment에는 변수a가 없기때문에outerEnvironmentReference(=outer함수의LexicalEnvironment) 참조.
2.inner함수의outerEnvironmentReference에도 변수a는 없기때문에,outer실행컨텍스트의outerEnvironmentReference(=전역컨텍스트의LexicalEnvironment) 참조.
3. 전역 컨텍스트의LexicalEnvironment에는 변수a가 있기때문에, 값 1이 출력이 됨.
outerEnvironmentRefence의 존재때문에 스코프 체인이 발생.outer의 LexicalEnvironment에 동일한 식별자가 있었다면, 그 식별자의 값을 찍음)var a = 1;
var outer = function(){
var inner = function(){
console.log(a);
var a = 3;
}
inner();
console.log(a);
}
outer();
console.log(a);
스코프 체인 과정.
1. 전역컨텍스트 활성화.environmentRecord에는{a,outer}식별자 저장하고 값 1과 함수 표현식을 할당. 이 때outerEnvironmentReference에는 아무것도 담기지 않음.
2.outer함수 호출.outer실행 컨텍스트가 활성화.
3.outer의 실행 컨텍스트의environmentRecord에는{inner}식별자를 저장하고 함수 표현식을 할당. 이 때outerEnvironmentReference는 전역 컨텍스트의LexicalEnvironment가 됨.
4.inner함수 호출.inner실행 컨텍스트가 활성화.
5.inner의 실행 컨텍스트의environmentRecord에는{a}식별자를 저장. 이 때outerEnvironmentReference는outer함수의LexicalEnvironment가 됨.
6.a값을 출력하려고하지만,호이스팅에 의해 식별자는 선언만 되어있고 값은 할당 되지않았기때문에undefined가 나옴.
7.inner함수호출이 종료면서 콜스택에서 제거.a값을 출력함.outer함수의LexicalEnvironment에는 변수a가 없기때문에,outerEnvironmentReference(=전역 컨텍스트Lexical Environment)를 참조. 변수a를 찾은결과 변수가 있기때문에1을 출력.
8.outer함수호출이 종료면서 콜스택에서 제거.a값을 출력함. 전역컨텍스트의LexicalEnvironment에는 변수a가 없기때문에,1을 출력.
9. 전역 컨텍스트에서의 작업이 종료되면서 콜스택에서 제거되고 종료.
eval함수 실행으로 생기는 컨텍스트, 함수 컨텍스트와 {}블럭 컨텍스트가 있음.