[ES6] Javascript Execution Context(실행문맥, 실행컨텍스트)

권준혁·2020년 11월 1일
1

javascript

목록 보기
11/19
post-thumbnail

실행문맥에 대해 포스팅해보겠습니다.
실행문맥을 모르고도 코딩을 할 순 있지만, 실행문맥에 대해 알아야
클로저나 호이스팅, this의 원리같은 것들을 이해하기가 쉬운 것 같습니다.

실행문맥,실행컨텍스트,Execution Context 같습니다

실행문맥은 자바스크립트가 실행되는 문맥으로 추상적인 개념입니다.
문맥에 따라서 자바스크립트 엔진이 순서와 범위 등 코드를 실행하는데 필요한 정보를 파악합니다.
자바스크립트 엔진이 사람이 짜놓은 코드를 기계(js엔진) 입장에서 읽기 쉽도록 정리해놓은 것 정도로 생각됩니다.
하나의 실행문맥이 하나의 실행구역이기도 합니다.

1. 컨텍스트의 생성과 순서

프로그램 내의 코드들이 모두 하나의 컨텍스트로 정리되진 않습니다.
(컨텍스트는 둘 이상의 종류가 있고 , 종류마다 특정 조건에 생성됩니다.)
다음은 컨텍스트의 종류입니다.

  • 전역 실행컨텍스트
  • 함수 실행컨텍스트
  • Eval 실행컨텍스트

이 중세 번째의 Eval컨텍스트는
MDN : Eval을 절대 사용하지 말 것을 읽어보시면 수 많은 취약점이 있어 사용하지 말 것을 권고합니다.
따라서, 사용하지 않을 것이니 Eval코드가 실행컨텍스트를 생성한다는 것 정도만 알면 되겠습니다.

전역컨텍스트

가장 기본이 되는 실행컨텍스트입니다. 자바스크립트코드가 처음 실행되면 생성됩니다. 코드 전체의 정보를 가집니다.

함수컨텍스트

함수가 호출되면 함수컨텍스트가 생성됩니다.


두 종류의 컨텍스트가 있습니다. 전역 컨텍스트는 자바스크립트 코드가 실행되면 생성되며 함수 컨텍스트는 함수가 호출되면 생성됩니다.

이 컨텍스트들의 실행 순서를 결정하는 것이 실행문맥 스택(stack)입니다.

스택은 LIFO의 자료구조입니다. 네이버 지식백과 : STACK을 참고해주세요

가장 처음에 코드가 실행될 때 생성되는 전역컨텍스트가 스택에 쌓입니다.
그리고, 코드에서 함수호출을 만나면 함수컨텍스트가 생성되에 스택에 쌓입니다.
자바스크립트 엔진이 코드를 모두 읽고, 컨텍스트를 모두 생성해서 스택에 쌓고 나면! 쌓여있는 스택의 꼭대기부터 순서대로 실행시킵니다.
(책을 쌓고 가장 위에있는 책부터 읽는 것과 같습니다.)


2. 컨텍스트의 생성과정 , Detail

위 단락에서 컨텍스트를 개괄적으로 살펴봤다면, 이 번 단락에서는 컨텍스트 하나를 자세히 들여다보겠습니다.

실행문맥의 생성과정은 두 가지로 나뉩니다.

  • Creation Phase
  • Execution Phase

Creation stage, Execution stage라고도 불립니다.
하나씩 보겠습니다.

2-1. Creation Phase

여기서 두 가지 일을 합니다.

인용 출처 링크

  1. LexicalEnvironment 생성
  2. VariableEnvironment 생성

인용 출처 , ES5,ES6 추상적인 구조

ExecutionContextES5 = {
  ThisBinding: <this value>,
  VariableEnvironment: { ... },
  LexicalEnvironment: { ... },
}
ExecutionContextES6 = {
  LexicalEnvironment = <ref. to LexicalEnvironment in memory>,
  VariableEnvironment = <ref. to VariableEnvironment in  memory>,
}

this binding이 ES6에서는 LexicalEnvironment에 포함된다.

ES6 에서 LexicalEnvironment와 VariableEnvironment 둘의 차이점은 전자가 함수 선언과 변수 (let과 const)의 바인딩을 저장하고 후자는 변수 var 만 저장한다 라고 합니다. 첫 번째의 LexicalEnvironment에 대해서만 우선 자세히 알면 되겠습니다.

LexicalEnvironment는 세가지 일을 합니다.

  • Environment Records

    • Declarative environment record - Identifier들을 저장 --> 변수, 함수, 인수(arguments)를 저장
    • Object environment record - global code에 대한 LexicalEnvironment. 글로벌 바인딩객체(브라우저 윈도우객체)를 저장하는 것이며, 각각의 바인딩객체의 속성에 대해 레코드에 새로운 항목이 포함된다 (예를 들어, 브라우저의 경우, 브라우저가 창 객체에 제공하는 속성과 방법을 포함하고 있다)
    • (전체적인 관점에서 객관적인 상관관계를 기록하는 듯? 하다.)*
  • Reference to the outer environment - outer lexical environment에 대한 접근을 의미합니다.
    현재 컨텍스트에서 변수,함수 등을 찾지 못하면 상위 컨텍스트에서 해당 값에 접근한다는 의미입니다.

  • This binding - this의 값이 여기서 결정됩니다. 전역 컨텍스트에서는 기본으로 글로벌, 윈도우로 설정되어 있습니다.

  • 함수컨텍스트에서는 object reference로 호출됐다면* this는 해당객체를 가리키게 되고,

  • object reference가 주어지지 않았다면*
    global객체(브라우저에서는 window객체)를 가리키게 됩니다.
    (엄격모드(strict mode)에서는 undefined를 가리킵니다.)

2-2. Execution Phase

이 단계에서는 모든 변수에 대한 할당이 수행되고 코드가 최종적으로 실행됩니다!


다시 정리하겠습니다. 컨텍스트의 생성과정의 첫 번째인 [Creation Phase]에서는?

해당 컨텍스트내의 인수목록(arguments),함수, 변수를 저장합니다. 값이 저장되지는 않으며 매핑됩니다.

사진 인용 출처

사진에서의 두번째 코드를보면 foo의 값에 매핑됩니다.

Reference to the outer environment 현재 컨텍스트에 없다면 상위컨텍스트에서 매핑합니다.

일종의 Scope Chain을 생성해 참조해야할 컨텍스트들과 그 우선순위를 정합니다. (ES5이후에는 직접적으로 ScopeChain이라고 지칭하지 않는다고 합니다.)

조건에따라 this 바인딩 합니다.

object reference가 주어졌느냐 아니냐가 바로 그 조건입니다.

코드 예 - this의 object reference가 주어졌을 때와 아닐 때

// 1.  object reference
const person = {
  name: 'peter',
  birthYear: 1994,
  calcAge: function() {
    console.log(2018 - this.birthYear);
  }
}
person.calcAge();
// 2.  no object reference
const calculateAge = person.calcAge;
calculateAge();

추상적인 형태를 보며 다시 한번 읽어보세요

  • GlobalExecutioncontext은 전역컨텍스트입니다.
  • FunctionExecution은 함수컨텍스트입니다.

사진 인용 출처

추상적인 형태 ▼

*이 번 내용을 보며 더 궁금한 내용은 위에 있는 출처 링크를 따라가서 보시기 바랍니다.
*


개괄적으로라도 머리속에 정리해서
호이스팅, 클로저, 함수선언식과 표현식, this바인딩 등에 대한 이해를 돕기 위한 목적으로 포스팅했습니다. 무작정 외우면 이 것들은 더 하기싫때문에..(개인적인 생각)

읽어주셔서 감사합니다.
피드백이나 오역, 잘못이해한 부분등은 감사하게 받겠습니다.

profile
웹 프론트엔드, RN앱 개발자입니다.

3개의 댓글

comment-user-thumbnail
2021년 5월 6일

let과 const의 경우는 블록단위로 스코프가 제한되는데 아래와 같은 상황에서 실행 컨텍스트의 Lexical Enviroment 구조가 궁금해지네요.
function Test() {
let a = 1;
{
let a = 3;
}
}

답글 달기
comment-user-thumbnail
2021년 5월 6일

아.. a 라는 변수가 할당되고 코드가 실행이되면서 값이 1에서 2로 바뀌겠군요.. 마지막 라인에서는 다시 1로 바뀌는건가..? 자문자답..

1개의 답글