23장 실행 컨텍스트
23.1 소스코드의 타입
-
소스코드의 타입은 4가지로 분류 전역코드, 함수코드, eval코드, 모듈코드
-
실행 컨텍스트도 소스코드의 평가에 따라 4가지로 생성 전역 실행 컨텍스트, 함수 실행 컨텍스트, eval 실행 컨텍스트, 모듈 실행 컨텍스트
23.2 소스코드의 평가와 실행(23-01)
-
엔진은 소스코드의 평가, 소스코드의 실행으로 2가지 과정으로 처리
-
소스코드 평가에선 실행 컨텍스트 생성, 변수와 함수 등의 선언문만 먼저 실행하여 생성된 식별자를 키로 실행 컨텍스트가 관리하는 스코프(렉시컬 환경의 환경 레코드)에 등록
-
소스코드 실행(런타임 시작)에선 실행에 필요한 변수나 함수의 참조를 실행 컨텍스트가 관리하는 스코프에서 검색해서 취득. 그리고 값의 변경 등 실행 결과는 다시 실행 컨텍스트가 관리하는 스코프에 등록
var x; // 소스코드 평가 단계에서 실행 컨텍스트의 스코프에 등록
x = 1; // 소스코드 실행 단계에서 스코프에 검색해서 x있으면 값 할당
23.3 실행 컨텍스트의 역할(23-02)
-
실행 컨텍스트의 역할 : 스코프, 식별자, 코드 실행 순서 등의 관리
-
책을 참고해서 아래코드 실행 흐름을 확인할 것 1.전역코드 평가, 2.전역코드 실행, 3.함수코드 평가, 4.함수코드 실행
// 전역 변수 선언
const x = 1;
const y = 2;
// 함수 정의
function foo(a) {
// 지역 변수 선언
const x = 10;
const y = 20;
// 메서드 호출
console.log(a + x + y); // 130
}
// 함수 호출
foo(100);
// 메서드 호출
console.log(x + y); // 3
23.4 실행 컨텍스트 스택(23-03)
-
말 그대로 스택 형식으로 구성되어 있음
-
1.전역 코드 평가와 실행, 2.foo함수코드 평가와 실행, 3.bar함수코드 평가와 실행, 4.foo함수코드로 복귀, 5.전역코드로 복귀
const x = 1;
function foo () {
const y = 2;
function bar () {
const z = 3;
console.log(x + y + z);
}
bar();
}
foo(); // 6
23.5 렉시컬 환경
-
렉시컬 환경이란 실행 컨텍스트를 구성하는 컴포넌트
-
렉시컬 환경은 2개의 컴포넌트로 구성 1.환경 레코드 2.외부 렉시컬 환경에 대한 참조
-
실행 컨텍스트가 코드 실행 순서를 관리한다면, 렉시컬 환경은 스코프와 식별자를 관리
-
책의 그림을 통해 참고하면 더 쉬움(여기부터 그림 정말 많음)
23.6 실행 컨텍스트의 생성과 식별자 검색 과정(23-04)
- 아래 예제를 통해 책에서는 실행 컨텍스트의 동작을 설명 시작
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
23.6.1 전역 객체 생성(23-05)
-
전역 객체는 전역코드가 평가되기 이전에 생성
-
전역 객체도 Object.prototype을 상속받음. 즉, 프로토타입 체인의 일원
// Object.prototype.toString
window.toString(); // -> "[object Window]"
window.__proto__.__proto__.__proto__.__proto__ === Object.prototype; // -> true
23.6.2 전역 코드 평가
-
사실 여기부터 정말 책을 봐야함. 그림으로 봐야지 예제론 이해못함 간단히 전역 코드 평가 순서와 함수 코드 평가 순서를 기록하겠다
-
전역 코드 평가 순서 1.전역 실행 컨텍스트 생성 2.전역 렉시컬 환경 생성 2.1.전역 환경 레코드 생성 2.1.1.객체 환경 레코드 생성(var) 2.1.2.선언적 환경 레코드 생성(const,let) 2.2.this 바인딩 2.3.외부 렉시컬 환경에 대한 참조 결정
-
함수 코드 평가 순서 1.함수 실행 컨텍스트 생성 2.함수 렉시컬 환경 생성 2.1.함수 환경 레코드 생성 2.2.this 바인딩 2.3.외부 렉시컬 환경에 대한 참조 결정
23-06
var x = 1;
const y = 2;
function foo (a) {
...
23-07
let foo = 1; // 전역 변수
{
// let, const 키워드로 선언한 변수가 호이스팅되지 않는다면 전역 변수를 참조해야 한다.
// 하지만 let 키워드로 선언한 변수도 여전히 호이스팅이 발생하기 때문에 참조 에러(ReferenceError)가 발생한다.
console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
let foo = 2; // 지역 변수
}
23-08
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); // ← 호출 직전
23-09
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);
23-10
console.hasOwnProperty('log'); // -> true
23.7 실행 컨텍스트와 블록 레벨 스코프(23-11)
- var는 함수 레벨 스코프, let과 const는 블록 레벨 스코프(이것도 그림을 통한 설명이 있음)
let x = 1;
if (true) {
let x = 10;
console.log(x); // 10
}
console.log(x); // 1
댓글남기기