혼자 적어보는 노트

[Javascript] 실행 컨텍스트(Execution Context) 본문

Javascript

[Javascript] 실행 컨텍스트(Execution Context)

jinist 2021. 12. 12. 04:39

실행컨텍스트란?

실행할 코드의 환경 정보들을 모아놓은 객체
실행컨텍스트를 구성하는 방법은 기본적으로 함수를 실행하는 것이다.

 

실행 컨텍스트는 아래와 같은 정보들을 담고있다.

-

variable Environment : 현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경정보
Lexical Environment : 처음에는 VariableEnvironment와 동일하다. 변경사항이 반영됨.

 

 

그리고 variable Environment와 LexicalEnvironment에는 두 가지의 정보가 담겨있다.

-

environment Record: 현재 컨텍스트와 관련된 코드의 식별자 정보들을 순서대로 저장
outer Environment reference: 상위의 LexicalEnvironment를 참조하는 포인터

ThisBinding : 식별자가 바라보는 객체, this의 값

 

 

이렇게 변수 정보를 먼저 수집하기 때문에 코드가 실행되기 전에 해당 환경에 속한 코드의
변수명들을 알게 되는 것이다.
자바스크립트 엔진은 식별자들을 최상단으로 끌어올린 후 코드를 실행한다고
하는데 호이스팅이라는 개념과 관계가 있는 것이다.

 

var num = 1;
function first() {
  function second() {
    console.log(num);
    var num = 10;
    function third() {
      console.log(num);
    }
    third();
  }
  second();
  console.log(num);
}
first();
console.log(num);

// undefined
// 10
// 1
// 1

 

위 코드에는 first(), second(), third()함수가 있다.

1. 처음 자바스크립트 코드를 실행하는 순간 전역 컨텍스트가 콜스택에 담긴다
2. first함수가 호출되어 first가 컨텍스트에 담긴다.
3. first함수 내부에서 second함수가 호출되어 first함수의 코드실행이 중단되고
second함수가 콜스택에 담긴다.
4. second함수 내부에서 console.log(num);을 실행하고 num변수에 10을 할당한다.
5. third함수가 호출되어 second함수는 중단되고 third가 콜스택에 담긴다.
6. third함수 내부의 console.log(num);가 실행되고 third함수는 종료된다.

 

third함수가 종료되어 콜스택에서 third가 사라지며 그 아래에 있는
second가 실행된다.

second에는 실행할 코드가 남아있지 않았기 때문에 바로 종료되며
second가 실행 컨텍스트에서 사라진다.
그 아래의 first컨텍스트가 실행되어 남아있던 console.log(num);를 실행하고 종료되며
first컨텍스트가 콜스택에서 제거된다.
그리고 전역 컨텍스트가 실행되며 남아있는 console.log(num)을 실행하고 종료되어
전역컨텍스트도 콜스택에서 제거된다.

 

그림으로 콜스택을 이해해보자.

 

실행 컨텍스트가 콜스택의 맨 위에 놓이면 해당 코드를 실행하게 되는 시점이 된다는 것을 알 수 있다.

아래서부터 하나씩 담겼다가 위에서부터 하나씩 제거되는 형식이다.

실행 컨텍스트의 Lexical Environment에는 무엇이 담겨 있을까?

어떤 정보로 인해 코드가 실행되는 것일까?

 

위의 코드에 담긴 컨텍스트들의 정보는 아래와 같다.

 

전역컨텍스트
environmentRecord: num, first

first
environmentRecord: second
outerEnvironment: 전역의 LexicalEnvironment

second
environmentRecord: third, num
outerEnvironment: first의 LexicalEnvironment

third
environmentRecord: 없음
outerEnvironment: second의 LexicalEnvironment

 

first함수가 실행되면 first의 컨텍스트 안에있는 식별자와 함수명을 

Environment Record에 저장한다.

그리고 second함수가 실행되었을때 num이라는 식별자를 찾는다.

second안의 num에는 아직 값이 할당되지 않았기 때문에

(호이스팅되어 변수 선언은 위로 올라갔지만 값 할당이 아래에 있기 때문)

undefind가 출력되고 이후에 num에 10이라는 값이 할당된다.

third함수가 실행되고 console.log(num);을 실행하기위해

evironmentRecord에서 num을 찾아보지만 없다.

third의 outerEnvironment는 second이기 때문에 second의 LexicalEnvironment를 참조하여

num값을 다시 찾는다. second에서 num에 10을 할당해주었기 때문에 그 값을 가져오게되어

thrid의 console.log(num);에서는 10이 출력되는 것이다.

 

사실 더 깊은 내용들이 있긴 하지만

위와 같이 이해를 하고 다시 더 깊게 다뤄봐야겠다.

Comments