[Javascript] 실행 컨텍스트 총정리 ② | 실행 컨텍스트 스택

Re_Go·2023년 12월 22일
0

Javascript

목록 보기
27/44
post-thumbnail

1. 실행 컨텍스트 스택(Excution Context Stack)이란?

실행 컨텍스트 스택이란 실행 컨텍스트에서 소스코드의 타입을 분류할 때 각각의 코드를 평가 후 해당하는 실행 컨텍스트를 생성하여 흐름에 따라 실행 컨텍스트 스택에 각각의 컨텍스트들을 추가(push) 하거나 제거(pop)하는 방식으로 스택 자료구조 방식으로 전체 코드의 실행 흐름을 제어하는 프로세스이며, 스택 방식인 LIFO(Last-in-First-out) 방식으로 해당 프로세스는 처리됩니다.

그리고 이러한 프로세스의 적재 특성은 LIFO 이므로 현재 스택에서 최상단에 위치한 컨텍스트는 현재 실행 중인 실행 컨텍스트라고도 불립니다. (가장 먼저 적재된 실행 컨텍스트는 스택의 밑바닥에 위치한 컨텍스트가 됩니다.)

① 전역 변수에 대한 소스코드의 평가 및 실행 예시) 전역 변수 및 함수의 평가 과정이 끝난 후 전역 객체의 프로퍼티와 메서드로 바인딩 되는 평가 단계와, 순차적으로 실행될때에는 변수에 값이 할당되고, 함수가 호출되면 순차 과정을 일시 중단하고 호출된 함수 내부로 진입하여 먼저 실행하는 과정을 거칩니다.

var x = 10; // var x와 10의 정보를 런타임 전에 렉시컬 환경에 등록 후 var x를 undefined로 초기화한 후에, 런타임에는 x가 선언된 변수, 즉 렉시컬 환경에 등록 된 변수인지를 확인 후 리터럴을 할당합니다.

② 함수 선언문에 대한 소스코드의 평가 및 실행 예시) 런타임 이전에는 함수 내의 선언된 선언문이 평가되고, 런타임 동안에는 해당 함수가 호출될 경우 다음 처리 순서에서 정지하고 해당 함수 실행을 실시한 후에, 해당 함수 실행이 종료되면 다시 정지되었던 해당 스코프로 이동 후 순차적으로 코드를 처리합니다.

function letsAdd(a){ // 함수가 호출되기 전인 런타임 이전에 함수 선언문의 매개변수 및
    const b = 20; // 지역 변수의 정보들이 렉시컬 환경에 등록되지만
    const c = 30;
    this.a = a; // this는 바인딩 된 객체에 따라 동적으로 결정되기 때문에 렉시컬 환경에 등록되지 않고 런타임 동안에 호출한 객체에 따라 this의 주체도 결정됩니다.

    console.log(a+b+c); // 변수 및 함수 등의 선언문을 제외한 나머지 코드는 런타임 동안, 즉 함수 내에서의 평가가 이루어진 후에 함수 내에 변수들에 순차적으로 리터럴이 할당 되면서 해당 코드의 차례에 도달할 때 해당 스코프 체인(프로토타입 체인 검색)을 검색 후 실행됩니다.
};

letsAdd(10); // 함수 호출시 아래 단계로 이동하는 것이 아니라 해당 함수로 이동 후 처리 과정이 끝나면 다시 여기서 다음 아래 단계(순차적으로)로 처리 됩니다.

③ 중첩 함수 사례로 알아보는 자세한 컨텍스트 스택 절차 및 소스코드의 평가 및 실행 예시) 중첩 함수의 경우, 각 함수 당 가지는 함수 실행 컨텍스트를 가지고 있으며, 스택 방식으로 관리가 되므로 실행 컨텍스트의 원리를 아는대에 중요한 역할을 합니다.

const x = 1; // 런타임 이전에는 const x로 등록 후 런타임 동안 x에 1을 할당합니다.

function add(){ // 런타임 이전에 전역 실행 컨텍스트에 등록되며, 런타임 동안 add가 호출되면 해당 함수를 실행 컨텍스트 스택에 적재합니다.
    const y = 2; // 해당 지역변수는 add 함수가 호출된 시점에 평가되고 런타임 동안에 값 할당이 이루어지며
    console.log(x+y) // 해당 메서드가 실행되어 실행을 한 후 중첩 함수 bar를 함수 실행 컨텍스트에 등록합니다.
    function sub (){ // 이후 해당 함수 호출시 내부의 지역 변수가 함수 컨텍스트에 등록되고, 런타임 동안 값을 할당하고 마찬가지로 메서드도 실행 후 종료합니다.
        const z = 3;
        console.log(z-y-x);
    }
    sub(); // sub 함수가 종료되면 실행 컨텍스트 스택에서 sub 함수를 제거(pop) 합니다.
}
add(); // 마찬가지로 add 함수가 종료되면 실행 컨텍스트 스택에서 add 함수를 제거(pop) 합니다.

★ 위 예시의 중첩 함수에 대한 다음 실행 컨텍스트 스택 순서는 다음과 같습니다.

  1. 런타임 전에 전역 변수 x와 및 함수 선언문(전역 함수)add를 전역 실행 컨텍스트에 등록
  2. 이후 전역 코드가 실행되어 전역 컨텍스트가 실행 컨텍스트 스택에 적재되어 순차적으로 변수 x에 값을 할당 후 함수 add를 호출합니다.
  3. 함수 add가 호출되면 함수 실행 컨텍스트에 지역 변수 y와 중첩 함수 sub가 등록 되고, 마찬가지로 해당 컨텍스트가 실행 컨테스트 스택에 적재된 후 런타임 동안 y에 값을 할당 후 console.log 수행 후 sub 함수를 호출합니다.
  4. 함수 sub이 호출되면 마찬가지로 함수 실행 컨텍스트에 지역 변수 z를 등록 후 실행 컨텍스트 스택에 sub 함수 컨텍스트가 적재된 후 런타임 동안 z에 값을 할당하고 console.log를 수행하고 최종적으로 sub 함수를 종료하는데, 이때 실행 컨텍스트 스택에 있던 해당 함수 컨텍스트를 제거(pop) 합니다.
  5. 마찬가지로 add 함수 복귀 후 더이상 실행할 코드문이 없을 경우 실행 컨텍스트 스택에서 제거하여 종료 후 최종적으로 전역 코드 복귀 후 마찬가지로 실행할 코드가 남아있을 경우 실행하고, 없을 경우 최종적으로 해당 전역 컨텍스트를 실행 컨텍스트 스택에서 제거하는 것으로 전체 코드문이 종료됩니다.

profile
인생은 본인의 삶을 곱씹어보는 R과 타인의 삶을 배워 나아가는 L의 연속이다.

0개의 댓글