실행 컨텍스트로 살펴보는 자바스크립트 동작원리

sudyn·2023년 8월 31일

JavaScript

목록 보기
4/14
post-thumbnail

자바스크립트의 내부 동작 방식을 이해하면 모호했던 호이스팅과 클로저를 이해하는 데에도 도움이 될 것이다.

그렇다면 실행컨텍스트가 무엇이길래

👉 실행 컨텍스트란 무엇일까?

context는 '문맥'이라는 의미이다. 이를 바탕으로 실행 컨텍스트는 코드의 문맥, 즉 코드가 실행되는 환경이라고 이해하면 쉽다. 실행컨텍스트(Execution context, EC)는 '자바스크립트 엔진이 코드를 실행하는데 필요한 환경을 제공하는 객체'다.

여기서 환경(environment) 이란 코드가 특정 시간, 상황에 접근할 수 있는 변수들, 객체들, 함수들 그리고 this를 의미한다.

이런 정보들을 저장해둔 덕에 코드가 여러 번 실행되어도 동일한 환경을 구성할 수 있다.

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

이 컨텍스트에 환경 타입에 대해 알아보자.

실행컨텍스트의 세가지 타입

1) 전역 실행 컨텍스트
자바스크립트 엔진이 스크립트 파일을 실행하기에 앞서 가장 먼저 전역 실행 컨텍스트가 생성된다.
전역 실행 컨텍스트는 프로그램 내 오직 하나만 존재한다.

2) 함수 실행 컨텍스트
함수가 호출될 때마다, 해당 함수에 대한 실행 컨텍스트가 생성된다. 각각의 함수들은 자신만의 실행 컨텍스트를 가지지만 실행 컨텍스트는 함수가 호출이 되어야 만들어진다.

3) eval 함수 실행 컨텍스트
eval() 함수를 사용하여 문자열 형태로 코드를 실행할 수 있다. eval도 실행 컨텍스트를 생성하나 자바스크립트 환경에서 잘 쓰이지 않는다.

👉 실행 컨텍스트 속엔 어떤 정보들이 있을까?

실행 컨텍스트 내부엔 variable environment, lexical environment, this binding 가 있다. 실행 컨텍스트는 이러한 정보들을 기반으로 코드의 실행 흐름을 관리하며, 스코프 체인을 통해 식별자에 접근할 수 있는 환경을 제공한다.

여기선 편의상 VariableEnvironment를 VE, LexicalEnvrionment를 LE라 표기했다.

✔️ VariableEnvironment(VE)

  • 먼저 실행 컨텍스트를 처음 생성하면 VE에 정보를 먼저 담는다.
  • 현재 컨텍스트 내의 식별자들에 대한 정보(변수, 매개변수, 함수 선언 등)외부 환경 정보를 저장하고 있다.
    1) environmentRecord
    2) outerEnvironmentReference
  • 이 VE를 복사해서 LE를 만들고 이후 LE를 주로 활용한다.
  • VE 에 담기는 내용은 LE 같지만, 최초 실행 시의 스냅샷을 유지한다는 점이 다르다.(이후의 변경사항이 반영되지 않는다.)

✔️ LexicalEnvironment

  • 실행 중에 변경 사항이 실시간으로 반영되는 환경정보를 저장한다.
  • VE와 비슷하지만 런타임 중에 변경사항을 반영할 수 있다.
  • 해당 함수가 실행될 때 변수에 접근하고 관리하는 데 사용된다.

LE의 구성정보를 보자면 ,

1) environmentRecord
해당 컨텍스트의 환경에 필요한 식별자 정보(매개변수 의 이름, 함수 선언, 변수명)를 기록한다. 더불어 실행 컨텍스트 내부 전체를 처음부터 끝까지 확인하며 순서대로 수집한다. 이는 호이스팅과도 밀접한 연관이 있다.

record로 호이스팅 이해하기

console.log(TVChanel); // undefined

var TVChanel = "Netflix";

console.log(TVChanel); // Netflix

위 코드를 자바스크립 엔진의 동작 과정으로 살펴보자.

  1. 코드가 실행되면 전역 실행 컨텍스트가 생성되고 콜스택에 쌓인다. 이 때 스캐닝 과정을 통해 변수의 선언을 찾는다.
  2. var TVChannel 선언을 만나면 실행 컨텍스트 내부의 EnvrionmentRecord에 TVChannel이라는 식별자를 등록한다.
  3. 그리고 해당 변수는 호이스팅되지만, 값은 초기화되지 않아 undefined로 출력된다.
  4. 이후 바인딩된 값에 Netflix를 기록한다.
  5. 마지막으로 다시 console.log(TVChannel);이 실행되면 이번에는 TVChannel 변수가 "Netflix" 값을 가지고 있으므로 "Netflix"가 출력된다.

이렇게 자바스크립트 엔진이 실행 컨텍스트를 구성할 때 environmentRecord 에 식별자의 정보를 수집한다. 이러한 과정을 통해 엔진은 함수를 실행하기도 전에 해당 컨텍스트 내부의 변수명들을 이미 알고 있게 된다.

이렇게 '식별자들을 코드의 최상단으로 끌어올렸다!' 라는 호이스팅이라는 개념이 생겨나게 된다. 이는 물리적으로 끌어올린 것이 아닌, 실행 컨텍스트 관점에선 이미 식별자들의 정보를 알고 있으니 식별자 정보를 수집하는 과정을 이해하기 쉬운 방법으로 나타낸 추상화한 가상 개념을 보면 된다.


2) outerEnvironmentReference
현재 호출된 함수가 선언된 당시의 LE를 참조한다.
변수에 접근을 할 때 해당 LE에서 발견된다면 해당 식별자를 사용하고 찾지 못할 경우 이 outerEnvironmentReference를 참조해 탐색하는 과정을 반복한다. 이런 과정을 스코프 체인이라 한다. outerEnvironmentReference는 스코프체인을 가능하게 하는 역할이다.

스코프체인

스코프 체인 : 변수에 접근할 때 해당 변수가 현재 렉시컬 환경에서 찾지 못하면 상위(외부) 렉시컬 환경으로 이동하여 변수를 찾는 과정

이 스코프 체인을 이해한다면 클로저의 개념에 대해서도 쉽게 이해할 수 있다.

✔️ ThisBinding

  • this 식별자가 바라봐야 할 대상 객체이다.
  • 실행 컨텍스트 생성시 즉, 함수 호출시 할당해주는 것으로 상황에 따라 동적으로 가리키는 값이 결정된다.

실행컨텍스트의 동작 원리

아래와 코드를 예시로 실행컨텍스트의 동작 원리와 과정을 살펴보자.

// ------------------------------ (1)
var a = 1
function outer() {
  function inner() {
    console.log(a) // undefined
    var a = 3
  }
  inner() // ------------------- (2)
  console.log(a) // 1
}
outer() // -------------------- (3)
console.log(a) // 1

1) (1) 자바스크립트 엔진이 코드를 실행하는 순간 전역 컨텍스트가 생성이 된다.
2) 전역 컨텍스트가 콜스택에 push된다.
3) 이후 (3) outer()함수가 호출되면 자바스크립트 엔진은 outer에 대한 환경정보를 수집한다.
4) 수집한 환경정보로 outer 실행 컨텍스트를 생성한다.
5) outer 실행 컨텍스트가 콜 스택의 전역컨텍스트 위에 push된다.

  • 전역 컨텍스트와 관련된 코드를 진행 중 기존의 전역 컨텍스트와 관련된 코드의 실행을 일시적으로 중단한 후 outer 실행 컨텍스트의 코드를 실행한다.
    6) (2) inner 함수도 위와 같이 콜스택에 쌓이게 된다.
    7) 가장 위의 활성화된 컨텍스트인 inner함수의 코드를 실행하고 함수가 종료 되면 콜스택에서 제거된다.
    8) 그 아래 outer 컨텍스트가 맨 위에 존재하므로 (2)다음줄부터 실행이 된다.
    9) 변수 a를 출력하면 outer 컨텍스트가 콜스택에서 제거되고, 전역 컨텍스트가 활성화된다.
    10) 실행을 중단했던 (3)의 다음줄부터 이어서 실행한다.
    11) a 변수 값을 출력하면 전역 공간에 실행할 컨텍스트가 없으므로 콜스택에서 전역 컨텍스트도 제거되어 종료된다.

🧹 정리하며

이렇게 실행컨텍스트를 이해하며 다양한 개념들에 대해 다뤄보았다.

  • 스코프
  • 스코프 체인
  • 식별자 결정
  • 호이스팅
  • 클로저
  • this

실행컨텍스트는 자바스크립트의 핵심 개념들을 이해하는데 필수적인 사전지식이다.

🔗 참고

정재남, 『코어 자바스크립트』, 위키북스(2019), p36-64.
https://joooing.tistory.com/entry/Javascript-%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8Execution-Context

https://medium.com/@happymishra66/execution-context-in-javascript-319dd72e8e2c

https://www.juicylog.com/-execution-context#4749fff631a54eadb1440c82441d2eba

profile
개발계발하는 프론트엔드 개발자🍠

0개의 댓글