From 74986fecfc508b7722627df07e16dc8a26a25285 Mon Sep 17 00:00:00 2001 From: Cheol-Won <76567238+Ryan-Dia@users.noreply.github.com> Date: Mon, 11 Dec 2023 22:50:45 +0900 Subject: [PATCH] =?UTF-8?q?docs:=2023.6=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\352\260\225\354\262\240\354\233\220B.md" | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git "a/docs/23_\354\213\244\355\226\211 \354\273\250\355\205\215\354\212\244\355\212\270/\352\260\225\354\262\240\354\233\220B.md" "b/docs/23_\354\213\244\355\226\211 \354\273\250\355\205\215\354\212\244\355\212\270/\352\260\225\354\262\240\354\233\220B.md" index cbd1dffa..ea53a90b 100644 --- "a/docs/23_\354\213\244\355\226\211 \354\273\250\355\205\215\354\212\244\355\212\270/\352\260\225\354\262\240\354\233\220B.md" +++ "b/docs/23_\354\213\244\355\226\211 \354\273\250\355\205\215\354\212\244\355\212\270/\352\260\225\354\262\240\354\233\220B.md" @@ -210,3 +210,117 @@ foo(); // 6 2. 외부 렉시컬 환경에 대한 참조 Outer Lexical Enviroment Reference 외부 렉시컬 환경에 대한 참조는 상위 스코프를 가리킵니다. 이때 상위 스코프란 외부 렉시컬 환경, 즉 해당 실행 컨텍스트를 생성한 소스코드를 포함하는 상위 코드의 렉시컬 환경을 말합니다. 외부 렉시컬 환경에 대한 참조를 통해 단방향 링크드 리스트인 스코프 체인을 구현합니다. + +## 6. 실행 컨텍스트의 생성과 식별자 검색 과정 + +```js +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); +``` + +### 1) 전역 객체 생성 + +전역 객체는 전역 코드가 평가되기 이전에 생성된다. +이때 전역 객체에는 빌트인 전역 프로퍼티와 빌트인 전역 함수, 그리고 표준 빌트인 객체가 +추가되며 동작 환경(클라이언트 사이드 또는 서버 사이드) 에 따라 +클라이언트 사이드 Web API 또는 특정환경을 위한 호스트 객체를 포함한다. + +전역 객체도 `Object.prototype`을 상속받는다. +즉, 전역 객체도 `프로토타입 체인의 일원`이다. + +```js +// Object.prototype.toString +window.toString(); // "[object Window]" + +window.__proto__.__proto__.__proto__.__proto__ === Object.prototype; // true + +``` + +### 2) 전역 코드 평가 + +👍 전역 코드 평가 진행 순서 + +전역 실행 컨텍스트 생성 + +전역 렉시컬 환경 생성 + +2.1 전역 환경 레코드 생성 + +2.1.1 객체 환경 레코드 생성 + +2.1.2 선언적 환경 레코드 생성 + +2.2 this 바인딩 + +2.3 외부 렉시컬 환경에 대한 참조 결정 + +### 3) 전역 코드 실행 + +이제 전역 코드가 순차적으로 실행됩니다. 변수 할당문이 실행되어 전역 변수 x, y에 값이 할당되고foo 함수가 호출됩니다. + +변수 할당문, 함수 호출문을 실행하려면 먼저 선언된 식별자인지 확인합니다. 또한 동일한 이름의 식별자가 다른 스코프에 존재한다면 어느 스코프의 식별자를 참조할지 결정하는데 이를 식별자 결정(identifier resolution)이라 합니다. + +식별자 결정을 위해 식별자를 검색할 때는 실행 중인 실행 컨텍스트에서 식별자를 검색하기 시작합니다. 만약 해당 실행 컨텍스트의 렉시컬 환경에서 식별자를 검색할 수 없으면 상위 스코프로 이동하여 식별자를 검색합니다. + +⇒ 이것이 스코프 체인의 동작 원리 +전역 렉시컬 환경은 스코프 체인의 종점이므로 전역 렉시컬 환경에서 검색할 수 없는 식별자는 참조 에러(ReferenceError)를 발생시킵니다. + +### 4) foo 함수 코드 평가 + +foo 함수가 호출되면 전역 코드의 실행을 일시 중단하고 foo 함수 내부로 코드의 제어권이 이동합니다. + +그리고 함수 코드를 다음 순서로 평가합니다. + +1. 함수 실행 컨텍스트 생성 +2. 함수 렉시컬 환경 생성 +2.1 함수 환경 레코드 생성 +2.2 this 바인딩 +2.3 외부 렉시컬 환경에 대한 참조 결정 + +### 5) foo 함수 코드 실행 + +이제 런타임이 시작되어 `foo` 함수 코드가 순차적으로 실행됩니다. 매개변수에 인수가 할당되고, 변수 할당문이 실행되어 지역 변수 x,y에 값이 할당됩니다. 그리고 함수 `bar`가 호출됩니다. + +이때 식별자 결정을 위해 실행 중인 실행 컨텍스트의 렉시컬 환경에서 식별자를 검색하기 시작합니다. 현재 실행 중인 실행 컨텍스트는 foo 함수 실행 컨텍스트이므로 foo 함수 렉시컬 환경에서 식별자 `x`, `y`를 검색해서 검색된 식별자에 값을 바인딩됩니다. 만약 식별자가 없으면 상위 렉시컬 환경으로 이동하여 식별자를 검색합니다. + +### 6) bar 함수 코드 평가 + +`bar` 함수가 호출되면 `bar` 함수 내부로 코드의 제어권이 이동하여 bar 함수 코드를 평가하기 시작합니다. 실행 컨텍스트와 렉시컬 환경의 생성 과정은 foo 함수 코드 평가와 동일합니다. + +### 7) bar 함수 코드 실행 + +이제 런타임이 시작되어 bar 함수 코드가 순차적으로 실행됩니다. 매개변수에 인수가 할당되고, 변수 할당문이 실행되어 지역 변수 `z`에 값이 할당됩니다. 그리고 `console.log(a+b+x+y+z)`가 실행됩니다. + +### 8) bar 함수 코드 실행 종료 + +`console.log` 메서드가 호출되고 종료하면 더는 실행할 코드가 없으므로 bar 함수 코드의 실행이 종료됩니다. 이때 실행 컨텍스트 스택에서 `bar` 함수 실행 컨텍스트가 `pop`되어 제거되고 스택에 남아있는 `foo` 함수 실행 컨텍스트가 실행중인 실행 컨텍스트가 됩니다. + +`bar` 함수 실행 컨텍스트가 제거되었다고 해서 bar 함수 렉시컬 환경까지 즉시 소멸하는것은 아닙니다. 객체를 포함한 모든 값은 누군가에 의해 참조되지 않을때 비로소 가비지 컬렉터에 의해 메모리 공간의 확보가 해제되어 소멸합니다. + +렉시컬 환경은 실행 컨텍스트에 의해 참조되기는 하지만 독립적인 객체입니다. 객체를 포함한 모든 값은 누군가에 의해 참조되지 않을 때 비소로 가비지 컬렉터에 의해 메모리 공간의 확보가 해제되어 소멸합니다. + +`bar` 함수 실행 컨텍스트가 소멸되었다 하더라도 `bar` 함수 렉시컬을 누군가 참조하고 있다면 `bar` 함수 렉시컬 환경은 소멸하지 않습니다. + +### 9) foo 함수 코드 실행 종료 + +`foo` 함수도 더 이상 실행할 코드가 남아있지 않으므로 foo 함수 코드의 실행이 종료됩니다. 실행 컨텍스트 스택에서 `foo` 함수 실행 컨텍스트가 `pop`되어 제거되고 전역 컨텍스트가 길생중인 실행 컨텍스트가 됩니다. + +### 10) 전역 코드 실행 종료 + +`foo` 함수가 종료되면 더는 실행할 전역 코드가 없으므로 전역 코드의 실행이 종료되고 전역 실행 컨텍스트도 스택에서 `pop` 되어 실행 컨텍스트 스택에는 아무것도 남아있지 않게 됩니다. + + +