실행 컨텍스트? 가 뭐에요?

ChangHyeon Bae·2022년 11월 26일
0

JavaScript

목록 보기
3/8
post-thumbnail

지난번 호이스팅에 대해 설명하면서 실행 컨텍스트에 대해 먼저 정리하고 했으면 더 좋겠다는 생각을 하게 됐다. 그래서 뒤늦게나마 실행 컨텍스트란 무엇인가에 대해 내 생각과 개념 그리고 과정을 정리해 보려고 한다!

지난 포스팅 : 호이스팅에 대해 설명하시오

🙋‍실행 컨텍스트(Excution Context)란?

  • 실행 가능한 코드가 실행되기 위해 필요한 환경정보들을 모아놓은 객체
  • scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트의 핵심 원리이다.
  • 이 과정에서 다른 언어에선 볼 수 없는 자바스크립트의 동적 언어로서의 성격을 가장 잘 파악 할 수 있는 개념이다.

📚 실행 컨텍스트의 종류

프로그램 내의 코드들이 모두 하나의 컨텍스트로 정리되지 않는다.
아래와 같이 3가지 종류의 컨텍스트들로 이루어져있다.

  • 전역 실행 컨텍스트 => 전역 영역에 존재하는 코드
  • 함수 실행 컨텍스트 => 함수 내에 존재하는 코드
  • Eval 실행 컨텍스트 => eval 함수로 실행되는 코드

이중 세번째의 Eval컨텍스트는
MDN: eval(), eval 코드 지양 을 읽어보면 수 많은 취약점이 발견되어 사용을 지양하기를 권한다. 따라서, 사용하지 않을 것이기 때문에 생성한다는 것만 명심하고 넘어가자!

💡 그리고 전역코드를 사용하기 보다는 함수코드를 사용하는 것이 바람직한 코드 작성법이기 때문에, 대부분의 경우 실행 가능한 코드란 콜 스택에 쌓이는 함수 코드 정보를 의미 한다고 한다.


🚀 실행 컨텍스트의 구조 & 실행

🤔 콜 스택

콜 스택에 실행 컨텍스트가 어떤 순서로 쌓이고, 어떤 순서로 코드 실행에 관여하는지에 대해 그림을 참고하면서 한번 살펴보자 !

💡 JavaScript 에서는 콜 스택실행 컨텍스트 스택이라고도 부르기도 한다. 하지만 편의상 콜 스택이라고 많이 부른다.

📝 실행 순서

var a = 1;

function outer() {
  function inner() {
    console.info(a); // undefined
    var a = 3;
  }
  
  inner();
  console.info(a); // 1
}

outer();
console.info(a); // 1

  1. 제일 먼저 코드가 실행되면서 콜 스택에 Global 실행 컨텍스트가 담긴다.
  2. Global 컨텍스트와 관련된 코드들을 순차로 진행하다가 Outer()라인에서 JS엔진은 Outer에 대한 환경 정보를 수집해서 Outer 실행 컨텍스트를 생성한 후 콜 스택에 담는다.
  3. Global 컨텍스트와 관련된 코드 실행을 일시 중단 후 Outer 실행 컨텍스트와 관련된 코드를 실행한다.
  4. Inner() 라인에서 Inner함수의 실행 컨텍스트가 Outer때와 같이 동일하게 콜 스택에 담기게 되고, JS는 Inner함수 내부 코드를 진행한다.
  5. 이어서 내부 함수가 종료되면, Inner는 콜 스택에서 제거되고, 순차적으로 Outer, Global 컨택스트 들이 스택에서 나오게 된다.

이렇게 어떤 실행 컨텍스트가 활성화 될 때 JS엔진은 해당 컨텍스트에 관련된 코드들을 실행하는 데 필요한 환경 정보들을 수집해서 실행 컨텍스트 객체에 저장한다.


위에 설명한 객체는 아래와 같은 정보들을 담고 있다.

  • VariableEnvironment: 현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보
  • LexicalEnvironment: 처음엔 VariableEnvironment와 같지만 변경 사항이 실시간 반영 됨
  • ThisBinding: this 식별자가 바라봐야 할 대상 객체

더 자세히 설명하자면,

VariableEnvironmentLexicalEnvironment의 내부는
environmentRecordOuterEnvironmentReference로 구성되어있다.


  • VariableEnvironment (변수환경)
    실행 컨텍스트를 생성할 때 VariableEnvironment에 정보를 먼저 담은 다음, 이를 복사해서 LexicalEnvironment를 만들고, 이후엔 LexicalEnvironment를 주로 활용 한다.

    • 변수 var만 저장

  • LexicalEnvironment(어휘적 환경)
    처음에는 VariableEnvironment와 같지만, 변경 사항이 실시간으로 반영 된다.

    • 함수 선언과 변수 (let 과 const)의 바인딩 저장한다.

    • DeclaretiveEnvironmentRecord -> 변수, 함수, 인수(arguments)를 저장한다.

    • ObjectEnvironmentRecord -> global code에 대한 LexicalEnvironment이다. Global 바인딩 객체(브라우저 윈도우객체)를 저장 하며, 각각의 바인딩 객체의 속성에 대해 레코드에 새로운 항목이 포함된다.

    • ThisBinding - this의 값이 여기서 결정 된다. Global 컨텍스트에 서는 기본으로 글로벌, 윈도우로 설정되어 있다.(실행 컨텍스트가 활성될 때 this가 지정되지 않은 경우 this에는 전역 객체가 저장)


      뭔가 글로 설명하다보니 머릿속에 안그려져서 그림으로 아래와 같이 정리해 봤다.


  • VariableEnvironement 와 LexicalEnvironment 공통 내부

    • environmentRecord(환경 레코드)
      함수 안의 코드가 실행되기 전에 현재 컨텍스트와 관련된 코드의 식별자 정보가 저장된다.
      즉, 코드가 실행되기전 JS엔진은 이미 해당 환경에 속한 코드의 변수명등을 알고 있다.

    • outerEnvironmentReference(외부 렉시컬 환경에 대한 참조)
      상위 스코프를 가리키며, 현재 record보다 바깥에 있는 record를 참고 한다는 뜻이다 (바깥 환경을 가리킨다라고 이해하면 된다.)
      상위 스코프에도 해당 식별자를 찾을 수 없을 시 에는 Reference Error가 발생 한다.

🧐 정리

앞서 말한 것과 같이 실행컨텍스트에 대해 공부하고 정리하면서 호이스팅과 스코프 개념과 같이 연결되는거 같아 호이스팅에 대해 공부를 할 때 애매했던 개념부분에 대해서 이번 실행 컨텍스트 정리를 통해 더 알게 된거 같다. 처음에는 그림없이 글로만 정리를 하는데 도저히 글로는 머릿속에 안그려져 직접 그려보거나 그림으로 남기니 더 이해가 잘되는거 같다.

🔗 참고

https://junilhwang.github.io/TIL/Javascript/Domain/Execution-Context/#_4-outerenvironmentreference%E1%84%8B%E1%85%AA-scope
https://poiemaweb.com/js-execution-context
https://junilhwang.github.io/TIL/Javascript/Domain/Execution-Context/#reference
https://bohyunkang.tistory.com/26
https://kellis.tistory.com/136
https://velog.io/@kwonh/ES6-Javascript-Execution-Context%EC%8B%A4%ED%96%89%EB%AC%B8%EB%A7%A5-%EC%8B%A4%ED%96%89%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8
https://www.youtube.com/watch?v=pfQfEwnJHRs

정확하지 않은 정보가 있을 수 있습니다. 댓글을 통해 피드백 주시면 적극적으로 반영하겠습니다🥲

profile
모든 결과는 내가 하기 나름이다 🔥

0개의 댓글