소스코드의 평가를 마친 뒤 실행한다
실행 컨텍스트란 ?
코드의 실행 순서를 관리하는 스택
실행 컨텍스트 스택에 최상위에 있는 실행 컨텍스트는 현재 실행중인 코드의 실행 컨텍스트(running execution context)
const x = 1;
function foo() {
const y = 2;
function bar() {
const z = 3;
console.log(x + y + z);
}
bar():
}
foo();


var x = 1;
const y = 2;
function foo (a) {
var x = 3;
const y = 4;
function bar (b) {
const z = 5;
console.log(a + b + x + y + z);
}
bar(10);
}
foo(20); // 42
전역 코드가 평가되기 이전에 전역 객체 생성
빌트인 전역 프로퍼티,함수와 표준 빌트인 객체가 추가
동작 환경에 따른 호스트 객체 추가
전역 객체도 Object.prototype을 상속받음

비어있는 전역 실행 컨텍스트를 생성, 실행 컨텍스트 스택에 푸시
전역 렉시컬 환경을 생성하고 전역 실행 컨텍스트에 바인딩

객체 환경 레코드 + 선언적 환경 레코드 = 전역 환경 레코드
객체 환경 레코드는 BindingObject(전역 객체)와 연결됨
전역 코드의 평가 과정에서 var 키워드로 선언한 전역 변수와 함수 선언문으로 정의한 전역 함수는 전역 환경 레코드의 객체 환경 레코드에 연결된 BindingObject를 통해서 전역 객체의 프로퍼티와 메서드가 된다
var x = 1;
const y = 2;
function foo (a) {
var x = 3;
const y = 4;
function bar (b) {
const z = 5;
console.log(a + b + x + y + z);
}
bar(10);
}
foo(20); // 42
x가 전역 객체의 프로퍼티로 등록된다, var이기 때문에 undefined로 초기화
foo()의 함수명과 동일한 foo라는 식별자를 전역 객체에 키로 등록하고 생성된 함수 객체를 즉시 할당
즉시 할당하기 때문에 함수 선언문 이전에도 호출이 가능해진다
let,const로 선언한 전역 변수는 선언적 환경 레코드에 등록
변수 선언과 초기화단계가 분리되어 진행되기 때문에 런타임에 변수 선언문에 도달할 때까지 일시적 사각지대
전역 환경 레코드의 [[GlobalThisValue]] 내부 슬롯에 전역 객체가 바인딩
전역 코드에서 this를 참조하면 [[GlobalThisValue]] 내부 슬롯에 바인딩된 전역 객체가 반환
외부 렉시컬 환경에 대한 참조는 현재 평가중인 소스코드의 상위 스코프
지금은 전역 코드를 평가중이기 때문에 null이 할당된다
x,y에 값이 할당되고 foo()가 실행됨
변수에 값을 할당하고 함수를 호출하려면 식별자를 찾아야한다
실행 중인 실행 컨텍스트에서 식별자를 찾는다
만약 현재 실행 중인 컨텍스트에서 식별자를 찾을 수 없다면 외부 렉시컬 환경에 대한 참조가 가르키는 상위 스코프로 이동해서 찾는다
JS엔진은 함수 정의를 평가하여 함수 객체를 생성할 때 현재 실행 중인 실행 컨텍스트의 렉시컬 환경을 함수의 내부 슬롯 [[Environment]]에 저장한다
함수 렉시컬 환경의 외부 렉시컬 환경에 대한 참조에 할당되는 것은 이미 전역 코드에서 함수에 대한 정의를 평가하여 함수의 내부 슬롯 [[Envoironment]]에 저장된 객체

var x = 1;
const y = 2;
function foo (a) {
var x = 3;
const y = 4;
function bar (b) {
const z = 5;
console.log(a + b + x + y + z);
}
bar(10);
}
foo(20); // 42
평가가 끝난뒤 foo 함수 내부의 소스코드가 실행된다
지역 변수 x,y에 값이 할당되고 bar함수를 호출
bar 함수 내부로 코드의 제어권이 이동
bar 함수의 실행 컨텍스트와 렉시컬 환경을 만든 뒤 실행 컨텍스트 스택에 푸시

z에 5 할당
console.log(a + b + x + y + z);실행
bar 함수 실행이 종료되고 실행 컨텍스트 스택에서 팝
실행 컨텍스트에서 bar 함수의 실행 컨텍스트가 제거됬다고 해서 bar 함수의 렉시컬 환경까지 즉시 소멸되지는 않는다
렉시컬 환경은 실행 컨텍스트에 의해 참조되지만 결국 독립적인 객체이다
객체를 포함한 모든 값은 누군가에 의해 참조되지 않을 때 가비지 컬렉터에 의해 소멸된다
bar 함수의 렉시컬 환경을 누군가는 참조하고 있다면 bar 함수의 렉시컬 환경은 소멸되지 않는다
foo 함수 실행 종료되고 실행 컨텍스트 스택에서 팝
전역 코드도 더이상 실행할 코드가 없으므로 실행 컨텍스트 스택에서 팝
실행 컨텍스트 스택은 emtpy
let x = 1;
if (true){
let x = 10;
console.log(x); // 10
}
console.log(x); // 1
if 문이 실행 되면 if 문의 코드 블록을 위한 블록 레벨 스코프를 새롭게 생성
선언적 환경 레코드를 갖는 렉시컬환경을 만든다(외부렉시컬참조는 기존의 것을 가르킴)
기존에 렉시컬 환경이 가르키던 것을 새롭게 생성한 것으로 변경
if 문이 종료되면 원래 상태로 복구
