실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체입니다.

 

자바스크립트는 어떤 실행 컨텍스트가 활성화되는 시점에 선언된 변수를 위로 끌어올리고(호이스팅, hoisting)

외부환경 정보를 구성하고, this 값을 설정하는 등의 동작을 수행합니다.

 

실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체라고 했는데, 

동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고

이를 콜스택(call stack)에 쌓아두었다가 가장 위에 쌓인 컨텍스트와 관련있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장합니다.

 

'동일한 환경'은 하나의 실행 컨텍스트를 구성할 수 있는 방법으로 전역공간, eval() 함수, 함수 등이 있습니다.

*ES6에서는 블록에서도 새로운 실행 컨텍스트가 생성됩니다.

  • 전역공간
  • eval
  • 함수 실행

 

전역컨텍스트는 자바스크립트 코드가 실행하는 순간 콜 스택에 담깁니다.

브라우저에서 실행 명령없이도 자동으로 실행하는 것외에 일반적인 실행 컨텍스트와 다른점은 없습니다.

즉, 자바스크립트 파일이 열리는 순간 전역 컨텍스트가 활성화된다고 이해하면됩니다.

 

코드에 따라 실행 컨텍스트가 콜스택에 쌓이는 예시를 간단하게 보겠습니다.

function a(){

	function b(){
    	// ....
    };
    
    b();
};

a();

콜스택에서의 실행컨텍스트의 변화

*실행이 종료되면 해당하는 실행컨텍스트가 콜스택에서 제거됩니다.

 

실행 컨텍스트는 활성화되는 시점에 쌓여있는 아래의 컨텍스트들의 환경정보들을 수집해서 실행컨텍스트의 객체에 저장합니다.

즉 b 함수 실행 컨텍스트가 활성화될 시점에 a의 환경정보를 b 실행컨텍스트의 객체에 저장한다는 의미입니다.

 

이때 저장되는 환경정보는 3가지로 나누어볼 수 있습니다.

  • VariableEnvironment

    • 현재 컨텍스트 내의 식별자 정보, 외부 환경 정보.

    • 선언 시점의 LexicalEnvironment의 스냅샷으로 변경 사항은 반영되지 않는다.)

  • LexicalEnvironment

    • 처음에는 VariableEnvironment와 같지만 실시간으로 변경사항이 반영됨.

  • ThisBinding

    • this 식별자가 바라봐야하는 대상 객체

 

 

VariableEnvironment

최초 실행 시(선언 시점)의 스냅샷.

실행 컨텍스트를 생성할 때 VariableEnvironment에 정보를 먼저 담은 후 이를 복사하여 LexicalEnvironment를 만든다.

이후에는 LexicalEnvironment를 주로 사용한다.

 

구성

  • environmentRecord
  • outer-EnvironmentReference

 

 

LexicalEnvironment

실행 컨텍스트를 생성할 때 VariableEnvironment를 복사하여 만든다.

VariableEnvironment보다 주로 사용되며 복사해왔기 때문에 VariableEnvironment와 구성이 동일하다.

 

구성

  • environmentRecord
  • outer-EnvironmentReference

 

 

environmentRecord

현재 컨텍스트와 관련된 코드의 식별자 정보(매개변수의 이름, 함수 선언, 변수명등)들이 저장됩니다.

컨텍스트 내부 전체를 처음부터 끝까지 훑으며 순서대로 수집한다.

변수 정보를 모두 수집 후에도 코드들은 실행되기 전이다.

이때 자바스크립트엔진이 코드 실행전에 변수들을 알게되기 때문에 호이스팅이라는 개념이 나오며

이때 식별자의 값에 대해서는 environmentRecord가 수집하지않기때문에 값은 할당하는 자리 그대로에 위치해 있습니다. 

*실제 자바스크립트 엔진이 변수를 끌어올리는 것이 아니며, 끌어올린다라고 표현한 이유는 변수 정보를 수집하는 과정을 이해하기 쉽기 위해 대체한 가상의 개념이다.

 

 

outer-EnvironmentReference

스코프(Scope)는 식별자에 대한 유효범위입니다.

ES5에서는 전역공간을 제외하면 오직 함수에 의해서만 스코프가 생성됩니다.

'식별자의 유효범위'를 안에서 부터 바깥으로 차례로 검색해 나가는 것을 스코프 체인(Scope Chain)이라고 하며

이를 가능하게하는 것이 LexicalEnvironment의 outer-EnvironmentReference입니다.

outer-EnvironmentReference는 현재 호출된 함수가 선언될 당시(할성화될 당시)의 LexicalEnvironment를 참조합니다.

 

스코프체인

outer-EnvironmentReference는 자신이 선언된 시점의 LexicalEnvironment만 참조하고 있기 때문에, 식별자를 찾기위해서는 계속 찾아 올라가여 식별자를 찾습니다. 그리고 이것을 스코프체인이라고 합니다.

이때 가장 먼저 발견되는 식별자에만 접근이 가능합니다. 

*최상위에 선언된 동일한 이름의 식별자에 접근할 수없게 상단에 동일한 이름으로 식별자를 선언하는 것을 것을 변수 은닉화(variable shadowing)라고 합니다.

 

콜스택에서의 실행컨텍스트의 변화

즉, b라는 함수가 식별자를 찾는다면 b의 outer-EnvironmentReference에서 선언될 당시의 LexicalEnvironment를 참조하고(즉 a의 LexicalEnvironment임) 이때 a에서도 해당하는 식별자를 찾지못한다면

a 함수의 outer-EnvironmentReference에서 LexicalEnvironment를 참조하여(전역컨텍스트의 LexicalEnvironment임) 식별자를 찾습니다.

 

 

ThisBinding

실행컨텍스트의 ThisBinding에는 this로 지정된 객체가 저장됩니다.

만약 실행컨텍스트의 활성화 당시 this가 지정되지 않을 경우 전역객체가 this로 저장됩니다.

 


 

출처

코어 자바스크립트:핵심 개념과 동작 원리로 이해하는 자바스크립트 프로그래밍,(저자 정재남)

 

+ Recent posts