위 코드의 실행 결과를 예측하고, 그 이유를 설명해주세요.
function foo() {
const value = 'foo의 const';
bar();
}
function bar() {
console.log(value);
}
foo();
const value = '전역의 const'
전역 객체 생성.
전역 코드 평가 단계에서, 함수 선언문으로 정의된 전역함수 foo와 bar는 전역 실행 컨텍스트의 Global Environment Record의 Object Environment Record에, 전역 변수로 선언된 const value는 Declarative Environment Record에 등록됨

foo 함수가 런타임에 실행되면 foo 함수 내부로 코드의 제어권이 이동하고, 함수 코드 평가 과정에서 foo 함수의 함수 실행 컨텍스트와 함수 Lexical Environment가 생성됨
함수 Environment Record 생성
함수의 Lexical Environment를 구성하는 컴포넌트인 함수 Environment Record에 foo 함수 내부에서 선언된 변수인 value가 등록된다(uninitialized)
this 바인딩
outer lexical environment reference 결정
함수 정의(함수 선언문, 표현식, 화살표 함수)가 평가된 시점에 실행 중인 실행 컨텍스트의 렉시컬 환경의 참조가 할당됨 ⇒ foo 함수가 평가된 시점에서 실행 중인 실행 컨텍스트는 전역 실행 컨텍스트!
⇒ foo 함수의 코드가 실행돼 value에 값이 할당되고 bar 함수가 호출됨
bar 함수가 실행되면 bar 함수 내부로 코드의 제어권이 이동하고, 함수 코드 평가 과정에서 bar 함수의 함수 실행 컨텍스트와 함수 Lexical Environment가 생성됨
console.log(value)에서 value값을 찾기 위해 running 실행 컨텍스트(bar 실행 컨텍스트)의 Lexical Environment의 Environment Record에 등록된 값을 검색
→ 없으니까 Outer Lexical Environment Reference를 통해 상위 스코프로 이동해 Lexical Environment 탐색
→ value가 전역 실행 컨텍스트의 Declarative Environment Record에 등록되어있긴 하지만, 아직 해당 코드 라인이 실행되지 않아 값이 할당되지 않은 uninitialized 상태
→ TDZ에 빠진다
→ ReferenceError 발생
빈칸 채우기
실행 컨텍스트는 ( 식별자 )의 등록과 관리 및 ( 코드 )의 실행 순서를 결정하는
자바스크립트의 내부 메커니즘이다.
실행 컨텍스트는 LexicalEnvironment 컴포넌트를 포함한다.
렉시컬 환경은 ( Environment Record )와 ( OuterLexicalEnvRef )로 구성된다.
( Env Record )는 식별자와 이에 바인딩된 값을 관리하는 저장소이고,
( OuterLexEnvRef )는 상위 스코프에 대한 참조를 가지고 있어
( 스코프 체인 )을 구현하는 데 사용된다.
전역 환경 레코드는 BindingObject에 바인딩된 ( Object Env Record )와,
let/const 키워드로 선언된 전역 변수를 관리하는 ( Declarative Env Record )로 구성된다.

선택지 (중복 사용 가능): A. 선언적 환경 레코드 B. 스코프 체인 C. Lexical Environment D. 객체 환경 레코드 E. Outer Lexical Environment Reference F. 코드 G. Environment Record H. 식별자
O/X 퀴즈
렉시컬 환경은 실행 컨텍스트의 컴포넌트이며, 실행 컨텍스트가 실행 컨텍스트 스택에서 제거될 때 메모리에서 항상 함께 소멸된다 (X)

함수 Environment Record는 Object Environment Record와 Declarative Environment Record를 가진다 (X)
‘전역’ Environment Record로 고쳐야함
식별자와 스코프는 실행 컨텍스트의 렉시컬 환경으로 관리하고, 코드 실행 순서는 실행 컨텍스트 스택으로 관리한다. (O)
Lexical Environment의 EnvironmentRecord가 식별자 관리 OuterLexicalEnvironmentReference가 스코프 관리
식별자 결정에 대해 설명하고, 아래 코드에서 console 키워드를 찾는 과정을 Outer Lexical Environment Reference, 식별자 결정과 스코프 체인을 통해 설명해주세요.
const x = 1;
function foo() {
const y = 2;
console.log(x + y);
}
foo();
식별자 결정: 변수 또는 함수 이름이 선언된 식별자인지, 동일한 이름의 식별자가 어느 스코프에 있는지 확인해서 어느 스코프의 식별자를 참조하면 되는지 결정하는 것
전역 코드 평가 단계
전역 실행 컨텍스트
전역 Lexical Environment 생성
x, foo가 전역 Lexical Environment의 Environment Record에 등록됨
this 바인딩
Outer Lexical Environment Reference 결정 ← 전역 실행 컨텍스트이므로 null
전역 코드 실행 단계
x에 1 할당, foo 함수 실행
foo 함수 코드 평가 단계
함수 실행 컨텍스트 함수 Lexical Environment 생성 y가 함수 Environment Record에 등록됨 this 바인딩 Outer Lexical Environment Reference 결정
Outer Lexical Environment Reference: 현재 평가 중인 소스코드(foo 함수)를 포함하는 외부 소스코드(전역 코드)의 Lexical Environment, 즉 상위 스코프를 가리킴
foo 함수 코드 실행 단계
y에 2 할당 → console.log(x + y) 를 만나면 console 식별자를 검색하기 시작함

console 식별자를 스코프 체인에서 검색
스코프 체인: running 실행 컨텍스트의 Lexical Environment에서 시작해, Outer Lexical Environment Reference로 이어지는 Lexical Environment의 연속
→ foo의 Lexical Environment의 Environment Record에는 y만 등록돼있고, key값으로 console을 찾을 수 없음
→ foo의 Lexical Environment의 OuterLexicalEnvironmentRecord가 가리키는 스코프 체인 상의 상위 스코프, 즉 전역 Lexical Environment로 이동
→ 전역 Lexical Environment의 Environment Record를 탐색함.
전역 Environment Record는 Object Environment Record와 Declarative Environment Record를 포함함.
Object Environment Record는 BindingObject 객체와 연결되어 있는데, 이 BindingObject가 브라우저 환경에서는 window 전역객체이며 console 식별자를 포함함.
→ 전역 Lexical Environment의 Environment Record를 탐색함.
전역 Environment Record는 Object Environment Record와 Declarative Environment Record를 포함함.
Object Environment Record는 BindingObject 객체와 연결되어 있는데, 이 BindingObject가 브라우저 환경에서는 window 전역객체이며 console 식별자를 포함함.
→ 전역 객체에서 찾은 console 식별자에 바인딩된 객체, 즉 console 객체에서 log 메서드를 검색함
→ 출력!