Execution context ( 실행컨텍스트 )

25tutmmu·2022년 9월 21일
0

ECMAScript 스펙에 따르면 실행 컨텍스트를 실행 가능한 코드를 형상화하고 구분하는 추상적인 개념으로
즉 실행 컨텍스트는 실행 가능한 코드가 실행되기 위해 필요한 환경을 의미합니다.
실행컨텍스트는 물리적으로는 객체의 형태를 가집니다.

컨텍스트의 종류

  1. 전역 컨텍스트
  2. eval 컨텍스트
  3. 함수 컨텍스트

전역 컨텍스트

기본의 컨텍스트로 자바스크립트코드가 처음 실행될때 실행됩니다. 코드 전체의 정보를 가지고 있습니다.
함수 내부에 없는 코드의 경우 모두 전역컨텍스트에서 실행됩니다.
브라우저의 경우 Window 객체를 생성하고 이를 글로벌 객체로 설정합니다.

함수컨텍스트

함수가 호출되면 함수컨텍스트가 생성됩니다.
각각의 함수마다 각각의 함수 컨텍스트를 가지고 있습니다.

실행컨텍스트 실행순서

실행컨텍스트 스택이 생성됩니다. 스택은 LIFO(Last In First Out) 후입선출구조!

script 요소를 처음으로 만나는 시점에서 전역컨텍스트를 생성하고 Execution Stack에 push합니다.
그리고 엔진이 함수 호출을 할 때마다 해당 함수에 대한 새로운 실행 컨텍스트를 생성해 Execution Stack의 맨 위로 푸시합니다.

var x = 'xxx';

function foo () {
  var y = 'yyy';

  function bar () {
    var z = 'zzz';
    console.log(x + y + z);
  }
  bar();
}
foo();

위 코드의 경우
실행컨텍스트 구조

함수 실행이 마무리되면 해당 컨텍스트는 사라집니다.페이지가 종료되면 전역 컨텍스트가 사라집니다.

실행컨텍스트의 3가지 객체

위에서 말한거 처럼 실행컨텍스트는 물리적으로 객체의 형태를 가지는데

아래의 3가지 프로퍼티를 소유합니다.

Variable Object (VO)

VO는 변수 ,매개변수(parameter), 인수정보(argument), 함수선언식(함수표현식 제외)을 포함하고 있습니다. 즉 해당 컨텍스트에서 실행에 필요한 여러가지 정보를 담은 객체라고 할 수 있습니다.

함수 컨텍스트와 전역 컨텍스트는 다른 VO를 가집니다.
전역 컨텍스트에서의 VO는 전역 객체를 가리킵니다.
전역객체는 arguments는 없고 window의 속성을 가지며 this를 써서 접근이 가능합니다.
즉 위 과정에선 window속성, 전역함수 foo와 전역변수 x를 가지고 있습니다.
foo() 함수 컨텍스트에선 arguments{} 객체, 내부함수 bar, 지역변수 y를 가지고 있습니다.

Scope Chain

스코프체인은 일종의 리스트 형태로 전역객체와 함수의 스코프를 차례로 저장하고 있습니다.

스코프 체인 = 현재 실행 컨텍스트의 변수 객체 + 상위 컨텍스트의 스코프 체인

전역 컨텍스트의 Scope Chain은 자기자신인 전역변수객체입니다.

함수 컨텍스트의 경우
현재의 스코프에서 검색해 보고 검색에 실패한다면 스코프 체인에 담겨진 순서대로 다시 검색을 하기 때문에 스코프체인이라고 불립니다. 검색에 실패할시 Reference 에러를 발생

  • var는 함수 레벨 스코프(Function-level scope) 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수로 전역객체에 property로 저장됩니다.

  • let const의 경우 블록 레벨 스코프(Block-level scope)
    모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없습니다. 즉, 코드 블록 내부에서 선언한 변수는 지역 변수입니다. let과 const로 선언한 변수는 전역 객체의 property로 할당되지 않습니다

실행컨텍스트를 이해하면 호이스팅개념 이해가능...

console.log(study) // undefined
var study = 'nestjs'
console.log(study) // 'nestjs'

console.log(study) // reference error
let study = 'nestjs'
console.log(study) // 'nestjs'

var의 경우 선언과 초기화가 동시에 일어나서 undefined 가 되고
let const의 경우 선언만 일어나기 때문에 reference error

nestjs 속 Execution context

nestjs에서 현재의 실행컨텍스트의 정보를 얻기 위한 방법은 두가지가 있는데 ArgumentHost를 이용하는 방법과 setMetadata데코레이터를 사용하는 것이다.

가드나 인터셉터 미들웨어 사용시 봤을텐데
http 사용시 host 객체는 [request, response, next] 배열 캡슐화
GraphQL 사용시 host 객체는 [root, args, context, info] 배열 캡슐화 하게됩니다

const [req, res, next] = host.getArgs();

// 인덱스를 이용해 특정 인수 가져오기
const req = host.getArgByIndex(0);

//인덱스 별로 요청 및 응답 객체하는 방식은
//맞는 어플리케이션을 사용되고 있는지 명확하지 않고 
//애플리케이션을 특정 실행 컨텍스트에 연결하므로 권장하지 않음
// -> 애플리케이션 컨텍스트로 전환하여 사용


const ctx = host.switchToHttp();
//Websocket: switchToWs() , RPC :switchToRpc()
const req = ctx.getRequest<Request>();
const res = ctx.getResponse<Response>();

라우터(controller)에서는 @SetMetadata() 커스텀 메타데이터를 사용할 수 있다 그러나 라우트에 연결하는 형식보단 롤 가드를 만드는 것이 일반적인 방법이다.

0개의 댓글