실행컨텍스트
1.실행컨텍스트
실행컨텍스트는 실행할 코드(대부분 함수 블록)에 제공할 환경 정보(변수, arguments 등)를 모아놓은 객체
실행컨텍스트를 구성하는 방법에는 전역 공간, eval()함수, 함수 가 있는데 전역공간은 자동으로 생성되는 거니까 제외하고
eval()은 보안 문제 등 여러 문제로 인해 사용하지 않으니까 제외하고
'함수'가 우리가 실행컨텍스트를 구성하는 방법이다.
실행컨텍스트는 VariableEnvironment, LexicalEnvironment 그리고 ThisBinding으로 이루어져 있는데
VariableEnvironment는 처음 생성할 때 생겼다가 대부분 LexicalEnvironment를 통해 코드를 진행하므로
LexicalEnvironment에 대해서 주로 공부하게 된다.
LexicalEnvironment는 EnvironmentRecord와 outerEnvironmentReference로 이루어진다.
2.EnvironmentRecord
코드가 실행되기 전에 변수 식별자 정보를 수집해서 EnvironmentRecord에 저장한다.
여기서 "호이스팅"개념이 등장한다.
처음에 호이스팅에 대해 배울 때, 선언 과정이 런타임 이전에 실행되어
마치 변수가 해당 스코프 최상단으로 끌어올려진 것처럼 행동하는 것이라고 이해를 했었다.
전역실행컨텍스트가 코드를 실행하기 전에 생성되고 이때 환경 레코드에 전역 변수, 함수, 매개변수의 식별자 정보를 저장한다.
이게 바로 '런타임 이전에 선언이 이루어진다' 고 외웠던 부분인 것 같다.
이때 환경 레코드에는 데이터가 할당된 상태가 아니라 식별자 정보만 들어간 상태이다.
변수를 예로 들면 var로 선언했는지, let으로 했는지에 따라 이 식별자가 어떤 메모리 주소를 가지고 있을지는 달라진다.
함수도 선언식으로 만들었는지, 표현식으로 만들었는지에 따라 달라진다.
중요한 것은 실행컨텍스트의 렉시컬 환경의 환경 레코드에 이런 정보들이 저장되고
코드 실행 이전에 식별자 정보를 저장하기 때문에 호이스팅이 발생한다는 것.
3. outerEnvironmentReference
어떤 함수가 실행되어 그 함수의 실행컨텍스트가 생성되면
outerEnvironmentReference(외부환경참조)는 선언될 당시의 렉시컬 환경을 참조한다.
실행이 아니라 선언이다.
이 선언이라는 것이 일어날 수 있는 환경은 다른 더 큰 범위의 실행컨텍스트가 활성화된 상태이다.
그러므로 외부환경 참조는 항상 선언될 당시의 상위 렉시컬 환경을 가질 수밖에 없다. 필연적으로
그래서 어떤 변수를 찾을 때 현재 실행된 나의 실행컨텍스트 함수 블록 안에서 환경 레코드를 뒤져서 찾아보고
없으면 외부환경참조를 타고 직전 실행컨텍스트의 스코프를 뒤지기 시작한다. 또 없으면 그 외부환경참조를 타고
더 앞의 실행컨텍스트를 뒤지다가 마지막엔 전역 스코프까지 도달한다. 전역 스코프에도 변수가 없으면
그제야 undefined를 보낸다. 이런 구조로 인해 가장 가까운 요소부터 접근하게 되고
여러 스코프에서 동일한 식별자를 선언한 경우, 무조건 가장 가까운 스코프 체인의 식별자를 참조한다.
즉, 가장 가까운 렉시컬 환경에 내가 찾는 식별자가 있으면 직전 렉시컬 환경을 찾지 않는다.
직전 렉시컬 환경의 식별자에는 접근할 수 없다. 이런 것을 은닉화라고 한다.
4. thisBinding
실행컨텍스트의 주요 기능 중 this를 바인딩하는 기능이 있다. 이건 다음에 자세히!
this를 알아야 객체지향 프로그래밍이 가능할 것 같다.
아직 확실히 이해하진 못했지만.. this를 이용해서 메서드를 재활용 가능하게 한다.
그리고 자바스크립트는 프로토타입이라는 객체의 원형을 항상 상속받는다.
이 프로토타입과 this를 사용한 메서드 재사용,
이런 걸 이용하는 게 객체지향 프로그래밍 아닐까..? 추측이 된다.