[코어 자바스크립트] Execution Context

소이뎁·2023년 7월 6일
0
post-thumbnail

🌈 인프런의 코어 자바스크립트(정재남) 수강 후, 이해한 내용을 정리한 글입니다.

Execution Context란

함수를 실행하는데 필요한 조건/환경정보를 담은 객체이다. Execution Context는 Call Stack에 쌓인다.

무슨 말이야

이렇게 생각해 보자. 파란 박스가 Call Stack이고 흰색 박스가 Execution Context라고 생각하자.

아래 코드를 실행하면

function outer() {
  function inner() {
    // ...생략...
  }
  inner()
}
outer()

이런 순으로 Call Stack에 Execution Context가 쌓이고 빠진다.

흰 상자를 더 자세히 살펴보자.

알다시피 흰 상자는 Execution Context이다. Execution Context 안에는 VariableEnvironment, LexicalEnvironment, ThisBinding이 있다.

여기서 중요한 것은 LexicalEnvironment이다.

LexicalEnvironment은 2가지로 구성되어 있다.

environmentRecordouterEnvironmentReference이다.

1) environmentRecord: 호이스팅 내부
environmentRecord를 키워드로 설명하면 호이스팅, 내부이다.

📍호이스팅
호이스팅이란 식별자 정보를 끌어올리는 것이다. 호이스팅은 코드 실행 전에 발생한다.

📍내부
호이스팅 과정에서 environmentRecord는 해당 Context 내부의 식별자 정보를 수집한다. 예를 들면, 왼쪽 코드는 호이스팅을 통해 오른쪽 코드로 변화한다.(함수는 함수 전체가, 나머지는 선언만 위로 끌어올려진다.)

이 과정에서 environmentRecord에는 아래의 정보가 담긴다.

이러한 정보는 호이스팅된 식별자 정보와 동일하다.

정리하면, environmentRecord에는 호이스팅을 통해 수집된 현재 Context 내부의 식별자 정보가 저장된다.

2) outerEnvironmentReference: 외부 스코프 체인
outerEnvironmentReference를 키워드로 설명하면 외부, 스코프 체인이다.

📍외부
outerEnvironmentReference는 현재 Context의 외부 LexicalEnvironment를 참조하는 것이다. 예를 들면, 아래 그림에서 왼쪽은 앞의 예시 코드에서 가져온 Call Stack이고 왼쪽을 구체적으로 그리면 오른쪽 그림이 된다.

오른쪽 그림을 자세히 살펴보자.

각각의 outerEnvironmentReference는 각각의 상위의 LexicalEnvironment를 참조한다. 따라서 각 Context들은 environmentRecord를 통해 각 Context에서 선언된 내부 식별자에 접근할 수 있을 뿐만 아니라 outerEnvironmentReference를 통해 외부 식별자에도 접근 가능하다.

결국, 핵심은 위의 그림에서 파란 박스의 Execution Context는 파란 박스 내부에서 선언된 식별자뿐만 아니라 그를 넘어선 노란 막대 영역의 외부 식별자까지 접근 가능하다는 것이다. 이러한 특성 때문에 outerEnvironmentReference에 의해 스코프 체인이 만들어진다.

📍스코프 체인
스코프 체인은 현재 실행중인 Context와 상위 스코프들의 연결된 구조를 말한다. 예를 들면, 아래 그림처럼 모든 Execution Context에 변수 a가 선언되어 있고, Inner Execution Context에서 console.log(a)를 실행했다고 가정하자. 그러면 console.log(a)는 본인 Context에서 선언된 var a = 1에 접근하여 1을 출력한다.

만약 본인 Context에 선언된 a가 존재하지 않는다면 상위 Context를 참조한다. 아래 그림에서, Outer Execution Context에 선언된 var a = 2가 있으므로 console.log(a)는 2를 출력한다.

만약 아래 그림처럼 Outer Execution Context에도 선언된 a가 없다면 또 한 번 상위 Context를 탐색하여 console.log(a)는 3을 출력한다.

정리하면, outerEnvironmentReference로 인해 각 Context는 외부 식별자에 접근 가능하고, 그로 인해 스코프 체인이 발생한다는 것이다.

다 이해했다면 문제를 풀어보자.

Q. 각 console.log(a)에서 출력되는 값은?

var a = 1
function outer() {
  console.log(a)

  function inner() {
    console.log(a)
    var a = 3
  }

  inner()

  console.log(a)
}

outer()
console.log(a)

A. 정답

var a = 1
function outer() {
  console.log(a) // 1

  function inner() {
    console.log(a) // undefined(호이스팅으로 a가 선언만 되고 할당은 안 되어 있기 때문)
    var a = 3
  }

  inner()

  console.log(a) // 1
}

outer()
console.log(a) // 1

3줄 요약

  • Execution Context는 함수를 실행하는데 필요한 조건/환경정보를 담은 객체이다.
  • Execution Context 안에는 LexicalEnvironment가 있고 LexicalEnvironment 안에는 environmentRecordouterEnvironmentReference가 있다.
  • environmentRecord는 호이스팅을 통해 내부 식별자 정보를 저장하고, outerEnvironmentReference는 외부 LexicalEnvironment를 참조하여 스코프 체인을 형성한다.

0개의 댓글