[ 실행 컨텍스트 (Execution Context) ]

carrotsman·2022년 4월 11일
4

프론트엔드

목록 보기
2/34
post-thumbnail

실행 컨텍스트 (Execution Context)

javascript 코드가 실행되는 환경 또는 연산 범위를 나타내는 추상 영역

실행 컨텍스트는 말만 가지나게 썼을 뿐, 개발자가 작성한 코드가 실행되기 위한 환경을 구성한 컨테이너다.
쉽게 말해서 우리가 계란 후라이를 하기 위해 가스 레인지와 프라이팬이 필요한 것 처럼 코드를 실행시키기 위해 선언해놓은 변수, 함수를 설정해놓고 실행시키는 개념이라 보면된다.
앞서 javascript 런타임 엔진은 Heap과 Stack 영역으로 구성된다는 것을 알고있다. 그럼 그 Stack에 실행될 코드가 어떤 구성으로 적재되는지 알아보겠다.


실행 컨텍스트 분류

개발에서는 어떤 개념이 존재하면 항상 분류가 나뉜다. 그래서 피곤하지.. 실행 컨텍스트도 2가지로 분류할 수 있다.

1. 글로벌 실행 컨텍스트 (Global Execution context)

런타임 엔진이 코드를 실행할 때 글로벌 실행 컨텍스트 영역이 생긴다. 생성 과정에서 전역 객체인 Window Object가 생성된다.

2. 함수 실행 컨텍스트 (Function Execution context)

javascript 코드로 선언된 함수가 호출될 때마다 호출된 함수 전용 실행 컨텍스트가 생긴다.

런타임 엔진이 코드를 실행할 때 최초 한번 Global Execution context 영역을 생성하고 함수가 호출될 때 마다 함수 전용 Function Execution context를 생성한다.


실행 컨텍스트 구조


Call Stack 실행 과정

Call Stack에 실행 컨텍스트를 쌓아가며 코드를 실행시킨다.
떡꼬치로 비유해서 생각하면 쉽다. 분식집 아주머니가 떡꼬치를 만들때 밑에서 부터 차례대로 꽂으신다. 그리고 우리가 쳐묵쳐묵할땐 위에서 부터 먹는다. 그런 구조와 같이 LIFO (Last in, First out) 구조를 띈 형태다.

코드와 그림으로 실행 과정에 대해 설명하겠다. 다음 코드는 요로코롬 실행된다.

// ES6
const first = () => {
    console.log('first')
    second();
}

const second = () => {
    console.log('second');
}

first();
// first
// second

이런 코드가 있다 가정해보자. first 함수에서 second 를 호출하는 구조를 띄고 있다. 내부적으로는 글로벌 실행 컨텍스트가 최초 1번 생기고 그 위에 함수별로 실행컨텍스트가 1개씩 생긴다. CallStack에 쌓을 땐 PUSH, 제거할 땐 POP이 이루어진다.

  1. step1 : 코드 실행 전 Global Execution context 생성 및 PUSH

  2. step2 : first 함수 호출
    (first 함수 Function Execution context 생성 및 PUSH)

  3. step3 : first 함수 내부 console.log('first') 호출
    (console.log 함수 Function Execution context 생성 및 PUSH)

  4. step4 : console.log(‘first’) 종료
    (console.log 함수 Function Execution context POP)

  5. step5 : second 함수 호출
    (second 함수 Function Execution context 생성 및 PUSH)

  6. step6 : second 함수 내부 console.log('second') 호출
    (console.log 함수 Function Execution context 생성 및 PUSH)

  7. step7 : console.log(‘second’) 종료
    (console.log 함수Function Execution context POP)

  8. step8 : second 함수 종료
    (second 함수 Function Execution context POP)

  9. step9 : first 함수 종료
    (first 함수 Function Execution context POP)

  10. step10 : 실행이 끝난 뒤 Global Execution context POP

  • 쉽게 말해 함수호출 한번당 실행 컨텍스트가 1개씩 생긴다. 그리고 Drilldown 구조로 컨텍스트의 생성과 제거가 이루어진다. 그니깐 예시를 보면 first안에 console.log 함수, second 함수 호출 코드가 있다. console.log 함수는 로그만 찍는 녀석이기 때문에 마지막 뎁스다. console.log 함수 컨텍스트 수행 이후 second 함수 실행 컨텍스트가 생성되는데 그 내부에서도 console.log('second') 를 호출하기 때문에 console.log 용 실행 컨텍스트가 생성되고 코드를 실행시킨다.

그 함수의 실행이 끝날때 까지 Function Execution context 는 유지된다고 생각하면 된다.


실행 컨텍스트 생성 과정

실행 컨텍스트의 생성은 생성과 실행 단계를 거쳐 구성된다.

  1. Creation Phase (생성 단계) - 이하 create
  2. Execution Phase (실행 단계) - 이하 execute

모든 실행 컨텍스트를 생성하는데 create > execute 단계를 거친다. 생성이랑 생성 단계의 구분을 위해 생성 단계는 create로 명시한다. 이 단계를 거치면서 this 객체 생성, 호이스팅이 일어나게 된다. 그리고 실행 컨텍스트가 글로벌이냐 함수냐에 따라 global object, argument 등 생성 인자의 차이가 존재한다.


1. 글로벌 실행 컨텍스트 (Global Execution context)

글로벌 실행 컨텍스트는 다음 create 단계를 거친다.

  1. Global Object를 생성한다.
  2. this 객체를 바인딩한다.
  3. 변수와 함수를 위한 메모리를 준비한다.
  4. 변수에는 undefined를 할당하고 함수 선언문은 실제로 메모리에 할당한다.

이후 execute 단계에서 undefined가 할당되어 있는 변수를 찾아 실제 값을 할당한다. 맞다. 호이스팅이 일어난다.

  • 다음 설명한 create, execute단계를 코드로 표현하자면 다음과 같다. 실제로 저런 내부 구조를 갖는다는건 아니지만 이해를 위해 json object 형태로 표현했다.
var name = 'carrots';
var age = 29;

function getUserInfo() {
    return {
        name: name, 
        age: age
    }
}
// 생성 단계 결과
Global Execution context : {
    Window : Global Object,
    this : Window,
    name : undefined,
    age : undefined,
    getUserInfo : function object
}

// 실행 단계 결과
Global Execution context : {
    Window : Global Object,
    this : Window,
    name : 'carrots',
    age : 29,
    getUserInfo : function object
}

2. 함수 실행 컨텍스트 (Function Execution context)

함수 실행 컨텍스트도 create, execute 단계를 거쳐 생성된다.

  1. arguments 객체를 생성한다.
  2. this 객체를 바인딩한다.
  3. 변수와 함수를 위한 메모리를 준비한다.
  4. 변수에는 undefined를 할당하고 (var 변수 경우만) 함수 선언문은 실제로 메모리에 할당한다.

글로벌 실행 컨텍스트와 차이는 전역 객체(Global Object) 대신 arguments 객체가 생성된다는 점이 다르다. 기타 다른 사항은 거의 동일하다. 함수 내부에서 사용되는 변수에 대해 호이스팅이 발생하는 점 또한 똑같다. arguments는 그 함수를 호출할 때 사용되는 파라미터의 모음이다.

  • 다음 설명한 create, execute단계를 코드로 표현하자면 다음과 같다. 실제로 저런 내부 구조를 갖는다는건 아니지만 이해를 위해 json object 형태로 표현했다.
var name = 'carrots';
var age = 29;

function getUserInfo(param) {
    var sex = '상남자';
    return {
        name: name, 
        age: age
    }
}

getUserInfo(1); // 실행 컨텍스트 생성
// 생성 단계 결과
Function Execution context : {
    argument : { 0 : 1, length : 1 }
    this : Window
    param : 1,
    sex : undefined
}

// 실행 단계 결과
Global Execution context : {
    argument : { 0 : 1, length : 1 }
    this : Window
    param : 1,
    sex : '상남자'
}

정리하며

javascript의 실행 단위인 컨텍스트의 종류와 내부적인 구조를 알아봤다. 떡꼬치를 상상하자.

오늘 저녁은 떡꼬치다. 🥕


참조 : https://medium.com/sjk5766/call-stack%EA%B3%BC-execution-context-%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90-3c877072db79

profile
당근먹고 강력한 개발

0개의 댓글