2023년 6월 28일조회 4572분 읽기
이론JS

실행 컨텍스트

🏭 실행 컨텍스트(EC)

자바스크립트 코드가 실행되고 연산되는 범위를 나타내는 추상적인 개념.

실행할 코드에 제공할 환경 정보들을 모아놓은 객체(ECO)

아래와 같은 두 단계를 거쳐 생성된다.

1. Creation Phase

LexicalEnvironment 생성

  1. 변수-식별자 맵핑 구조
  2. 렉시컬 환경 정보가 계속 바뀜

Variable Environment 생성

  1. 해당 EC 안에서 변수 상태에 의해 생성된 바인딩을 보유하는 렉시컬 환경
  2. 렉시컬 환경 정보가 생성됐을 때 값을 유지

2. Execution Phase

변수 할당 끝나고 코드 실행



🌍 전역 실행 컨텍스트(GEC)

기본 실행 컨텍스트로 함수 내부에 없는 코드는 전역 컨텍스트에서 실행

⭐ 단 한 개만 정의되는 전역 Context

GEC의 this -> window(browser) | global(node)

JS 작동원리 Call Stack에서 제일 처음 들어가 있으며 FEC를 실행시킨다.

🔨 함수 실행 컨텍스트(FEC)

함수 실행(호출)될 때 마다 정의되고 GEC 위에 올라가 실행되는 Context

JS 작동원리의 Call Stack에서 실행되는 함수의 단위



Example

javascript
let front = 'react';
let back = 'spring';
let browser = 'chrome';
var appStack;

function createApp(...stacks){
	let devops = 'aws';
  	stacks.push(devops, browser)
    return stacks
}

appStack = createApp(front, back);

1. Execution Phase 전 GEC의 형태

일반 코드, 변수가 작동하는 것과 같이 동작한다.

처음 초기화를 하기 전에 선언


text
GlobalExectionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // 식별자 바인딩
      front: < uninitialized >,
      back: < uninitialized >,
      browser: < uninitialized >,
      createApp: < func >
    }
    outer: <null>,
    ThisBinding: <Global Object>
  },
  VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // 식별자 바인딩
      appStack: < uninitialized >,
    }
    outer: <null>,
    ThisBinding: <Global Object>
  }
}

2. 변수 할당이 끝난 후 GEC

선언한 변수에 값 초기화


text
GlobalExectionContext = {
LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      // Identifier bindings go here
      front: 'react',
      back: 'spring',
      browser: 'chrome',
      createApp: < func >
    }
    outer: <null>,
    ThisBinding: <Global Object>
  },
VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Object",
      appStack: undefined,
    }
    outer: <null>,
    ThisBinding: <Global Object>
  }
}

3. 함수가 호출된 FEC

함수 호출했으니 함수 실행하기 위해 렉시컬이 FEC로 넘어간다.

outer(GEC)에서 외부에 참조해야하는 값이 있는지 확인한다. 여기서는 하나의 바로 GEC를 참조하기 때문에 browser(만약 node.js라면 node) 값 있는지 확인


text
FunctionExectionContext = {
LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      Arguments: {front: 'react', back: 'spring', length: 2},
    },
    outer: <GlobalLexicalEnvironment>,
    ThisBinding: <Global Object or undefined>,
  },
VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      stack: undefined
    },
    outer: <GlobalLexicalEnvironment>,
    ThisBinding: <Global Object or undefined>
  }
}

4. 실행 단계가 된 FEC

함수 실행 끝나고 다시 GEC로 렉시컬 넘어감


text
FunctionExectionContext = {
LexicalEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      Arguments: {front: 'react', back: 'spring', length: 2},
    },
    outer: <GlobalLexicalEnvironment>,
    ThisBinding: <Global Object or undefined>,
  },
VariableEnvironment: {
    EnvironmentRecord: {
      Type: "Declarative",
      stacks: ['react', 'spring', 'aws', 'chrome']
    },
    outer: <GlobalLexicalEnvironment>,
    ThisBinding: <Global Object or undefined>
  }
}

🎨 간단한 그림

  1. GEC 정의
  2. GEC 안에 있는 FEC 정의 후 실행
  3. GEC 위에 올라왔던 FEC 제거


🏇 Lexical Environment

Lexical 중첩 구조를 기반으로 특정 변수 및 함수에 대한 식별자(unique)의 연결을 정의

Environment Record과 null이 될 수 있는 Lexical 외부 환경 참조로 구성

함수 정의, 블록, try-catch 등 특정 구문 구조와 연결되며 코드가 평가 완료될 때마다 새로운 Lexical Environment 생성

각 렉시컬 환경은 세가지 모듈을 가짐

🧾 Environment Record

관련 렉시컬 환경범위 내에서 생성된 식별자 바인딩을 기록

🧱 outerEnvironmentReference (외부 환경 참조)

렉시컬 환경 값들이 논리적으로 중첩돼있는 모델을 사용함

내부(현재) 렉시컬 환경을 논리적으로 감싸고 있는 렉시컬 환경(외부)의 참조 -> 내부 렉시컬에서 외부 렉시컬의 변수에 접근할 수 있게 해줌

🔏 this binding

this의 값이 결정, 설정된다.

FEC에서 this는 함수가 어떻게 호출되는지에 달렸다.

객체 참조에 의해 호출되면 this의 값은 해당 객체로 설정된다. 아니라면 전역 객체나 undefined로 설정된다.



참고

https://catsbi.oopy.io/fffa6930-ca30-4f7e-88b6-28011fde5867

http://dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts/

https://stackoverflow.com/questions/9384758/what-is-the-execution-context-in-javascript-exactly

https://262.ecma-international.org/6.0/#sec-execution-contexts

https://262.ecma-international.org/6.0/#sec-executable-code-and-execution-contexts

https://blog.bitsrc.io/understanding-execution-context-and-execution-stack-in-javascript-1c9ea8642dd0

https://www.freecodecamp.org/news/how-javascript-works-behind-the-scene-javascript-execution-context/

https://velog.io/@edie_ko/js-execution-context