#back_to_basic
다시 처음부터!라는 마음으로 공부해보자
1. 실행 컨텍스트란
실행 컨텍스트(Execution Context)는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
자바스크립트는 동일한 환경에 있는 환경 정보들을 모은 실행 컨텍스트를 콜스택에 쌓아올린 후 실행하여 코드의 환경과 순서를 보장할 수 있게 한다.
스택은 FILO(First In, Last Out)의 구조이기때문에 순서를 보장할 수 있고, 그러므로 콜스택 내부에 쌓인 실행 컨텍스트의 정보를 통해 환경을 보장할 수 있다.
여기서 말하는 환경은 전역공간이 될 수도 있고, 함수 내부의 환경이 될 수도 있다.
처음 자바스크립트 코드를 실행하면, 위 사진의 (1)처럼 전역 컨텍스트가 콜스택에 담긴다.
1) 콜스택엔 전역 컨텍스트를 제외하곤 다른 컨텍스트가 없기에 전역 컨텍스트와 관련된 코드를 진행한다.
2) 전역 컨텍스트와 관련된 코드를 진행 중, a함수를 실행하였으므로 a 함수의 환경 정보를 수집하여 a 실행 컨텍스트를 생성하여 콜스택에 담는다.
3) a 함수 내부에서 b함수를 실행하였기에, 똑같이 b함수의 환경 정보를 수집하여 b 실행 컨텍스트를 생성하고 콜스택에 담는다. 이 전과 똑같이 콜스택 최상단에 b 실행 컨텍스트가 있기에 기존 a 실행 컨텍스트와 관련된 코드의 실행을 일시적으로 중단한다.
4) b 함수가 종료된 후 b 컨텍스트는 콜스택에서 제거된다. 제거된 후엔 콜스택 최상단엔 a 실행 컨텍스트가 있게 되고, 이전에 중단된 지점부터 코드 진행이 재개된다.
5) a 함수 또한 종료된 후 실행 컨텍스트가 콜스택에서 제거된다.
이후 전역 공간에 실행할 코드가 남아있지 않다면, 콜스택에서 전역 컨텍스트 또한 제거되며 콜스택엔 아무 것도 남지 않은 상태로 종료된다.
이 실행 컨텍스트는 아래와 같은 경우에 콜스택에 쌓이게 된다.
- 전역공간은 자동으로 콜스택에 쌓인다
- 함수를 실행하는 경우
- eval() 함수를 실행하는 경우
- block을 만드는 경우
위 실행 컨텍스트에 대한 개념은 생할 코딩 영상을 보면 이해가 더욱 쉽다.
1) 위 사진을 보면 디버거를 통해 실행 컨텍스트를 확인하고 있는데, Scope 아래엔 Script와 Global이 있다.
여기(js)서 Global은 window를 뜻하고, 어디에서나 접근 가능한 영역이다.
예를 들어 우리가 알림창을 띄우기 위해 사용하는 alert는 이 Global 영역에 있으며,
window.alert()로 호출 가능하다.
2) 위 사진에서 Call Stack이 있는데, 이는 execute context가 쌓이는 스택이다.
call stack에 쌓이는 실행 컨텍스트가 하나의 폴더라면, scope를 파일들이라고 표현할 수 있다.
제일 처음 쌓이는 컨텍스트는 글로벌 컨텍스트이고,
그 다음 쌓이는 컨텍스느는 fn1이 되겠다(함수 호출을 한 경우).
3) 해당 스코프에서만 사용할 수 있도록 변수를 선언시킬 수 있도록 해야한다.
❓ 스코프
스코프란 식별자에 대한 유효범위이다.
예를 들어, Scope A의 외부에서 선언한 변수는 A의 외부/내부 모두 접근이 가능하지만,
A 내부에서 선언한 변수는 오직 A의 내부에서만 접근할 수 있다.
스코프의 개념은 대부분의 언어에 존재하지만, ES5까지의 Javascript는 오직 함수에 의해서만 스코프가 생성된다고 한다.
위 영상에서도 이야기가 나오지만, 이러한 스코프를 통해 변수나 메소드를 검색할 때 타고타고 올라가서 검색을 하게 된다.
이를 scope chain라고 하며, 식별자의 유효범위를 안에서 바깥으로 차례로 검색해나가는 것을 의미한다.
2. 실행 컨텍스트가 가지는 정보들
위에서 실행 컨텍스트는 '코드가 실행되기 위해 필요한 정보들을 모아놓는 객체'라고 하였는데, 여기서 말하는 '필요한 정보'는 무엇일까?
- VariableEnvironment
- 현재 컨텍스트 내의 식별자(변수)들에 대한 정보
- 선언 시점의 스냅샷
- 컨텍스트를 생성할 때 VariableEnvironment에 정보를 먼저 담은 다음 이를 복사하여 LexicalEnvironment를 만든다
- LexicalEnvironment
- 처음엔 VariableEnvironment와 같지만, 변경 사항이 실시간으로 반영된다
- 주로 활용되는 환경 정보(VariableEnvironment는 스냅샷 유지를 목적으로 사용됨)
- environmentRecord(호이스팅 발생)와 outerEnvironmentReference(로 인해 스코프와 스코프체인이 형성)로 구성
- ThisBinding
- 식별자가 바라봐야할 대상 객체
가 있다.
❓ environmentRecord & Hoisting
자바스크립트는 코드를 실행하기 전에 식별자를 수집한다.
즉, 코드가 실행되기 전에 자바스크립트의 엔진은 이미 실행 컨텍스트에 속한 변수명들을 모두 알고 있는 셈이다.
이 때 바로 호이스팅 개념이 사용되는데,
엔진의 실제 동작 방식 대신에 자바스크립트 엔진은 식별자들을 최상단으로 끌어올려놓은 다음, 실제 코드를 실행한다고 생각하면 된다.
*호이스팅은 코드 해석을 좀 더 수월하게 하기 위해 environmentRecord의 수집 과정을 추상화한 개념이다.
environmentRecord는 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장되며,
매개변수 식별자 & 함수 자체 & 함수 내부의 식별자 등을 저장한다.
예시)
위 코드에서 식별자는 매개변수와 x가 있었는데, 변수들을 정의하는 부분들이 위로 끌어올려진다.
호이스팅은 변수 선언부와 함수 선언문에 발생을 한다.
❓ outerEnvironmentReference와 Scope
위에서 scope과 scope chain을 언급하였는데, scope chain을 가능하게 하는 것이 바로 outerEnvironmentReference이다.
outerEnvironmentReference는 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조한다.
즉, outerEnvironmentReference는 상위(직전) 컨텍스트의 LexicalEnvironment 정보를 참조하여 스코프를 형성하고, 이 스코프 체인을 통해 상위 컨텍스트에 접근할 수 있다.
References
화이팅!
'Web' 카테고리의 다른 글
[BB] Javascript: 비동기 프로그래밍 (0) | 2023.10.25 |
---|---|
[BB] JavaScript: var, let, const의 차이 (0) | 2023.10.25 |
[BB] Javascript의 기본 자료형 (0) | 2023.10.24 |
[BB] CSS와 곁들여 보는 DOM (0) | 2023.10.24 |
[BB] Javascript이란 (0) | 2023.10.23 |