실행 컨텍스트 ( Execution Context )

Evan Lee ㅣ 2023. 10. 22. 20:15

실행 컨텍스트란 ? 

실행 가능한 코드가 실현되기 위해 필요한 환경입니다. 브라우저의 자바스크립트 엔진이 자바스크립트 코드의 변환 및 실행을 처리하기 위한 특수한 환경을 생성하는데 이를 실행 콘텍스트라고 합니다. 여기에는 현재 실행중인 코드와 실행을 지원하는 모든 것들이 담겨 있는데, 실행 컨텍스트 런타임 동안 특정 코드가 파서에 의해 파싱되고, 변수와 함수가 메모리에 저장되며 실행가능한 바이트 코드가 생성되고 실행됩니다. 

 

 

실행 컨텍스트의 종류 

 

전역 실행 컨텍스트 (GEC, GO)

자바스크립트 엔진이 스크립트 파일을 받게되면 함수 내부에 존재하는 코드 외 모든 코드(빌트 인 객체, BOM , DOM, 전역 변수가)를 기반으로 처음에 전역 실행 컨텍스트를 생성하게됩니다. 그래서 모든 자바스크립파일에는 하나의 전역 실행 컨텍스트만 존재 합니다. 

 

함수 실행 컨텍스트 (FEC, AO)

함수가 호출될때마다 자바스크립트 엔진은 함수 실행 컨텍스트라고 불리는 각기 다른 타입의 실행 컨텍스트를 생성하는데 그 호출된 함수 내의 코드(함수선언, 매개변수, 변수)를 평가하고 실행합니다. 호출되는 매 함수는 독자적인 함수 실행 컨텍스트를 갖게되고 이때문에 스크립트 런타입에 함수 실행 컨텍스트는 여러개가 될 수 있습니다. 

 

 

실행 컨텍스트 2단계 

실행 컨텍스트가 생성되는 과정에는 크게 두가지가 있습니다. 

 

1. 생성 단계 ( Creation phase ) 

 

1) 변수 객체(VO) 생성 

변수 객체에 실행 컨텍스트내에 정의된 변수와 함수를 저장합니다. 전역 실행 컨텍스트에서 var 키워드로 선언된 각 변수를 가르키면 'undefined'로 설정된 프로퍼티가 추가되고, 모든 함수 선언에 대해서도 프로퍼티가 추가되고 메모리에 저장됩니다. 그래서 코드가 실행되기 전에 전역 함수 선언에 대해서 VO내에 저장이 되기대문에 엑세스가 가능합니다. 

 

 

호이스팅 

함수와 변수 선언은 자브스크립트에서 호이스팅이 됩니다. 위에서 언급되었듯이 실행 컨텍스트에서 이미 해당 함수와 변수가 변수 객체 메모리에 저장이 되었기 때문에 코드 실행전에 실행 컨텍스트 내에서 사용가능하기 때문이죠. 

 

하지만 모든 함수, 변수가 호이스팅이 되지는 않습니다. 함수는 표현식이 아닌, 선언식으로 정의된 함수만 호이스팅이 됩니다. 왜냐하면 표현식으로 선언된 함수는 변수로써 호이스팅이 되기때문에 아래 코드에서 `print3`가 실행 될때 print3는 undefined이기 때문에 에러가 뜨게 되죠. 

 

그리고 변수 호이스팅에서는 `let` 과 `const` 키워드를 사용해서 초기화를 하면 호이스팅이 안됩니다. 왜냐하면 temporal dead zone이 선언 이전의 변수 사용을 엄격하게 금지하고 있기 때문입니다. 

 

 

 

2) 스코프 체인 생성 

변수 객체(VO)를 생성한 후에는 실행 컨텍스트 생성 단계의 다음 단계로 스코프 체인을 생성합니다. 자바스크립트의 스코프는 코드 조각이 코드베이스의 다른 부분에 얼마나 접근 가능한지를 결정하는 메커니즘입니다.

함수 실행 컨텍스트는 스코핑이라는 프로세스를 통해 정의한 변수와 함수에 액세스할 수 있는 공간/환경인 스코프를 생성합니다. 이는 코드베이스 내에서 코드가 있는 위치를 의미합니다.

함수가 다른 함수에 정의되어 있는 경우 내부 함수는 외부 함수에 정의된 코드와 부모 함수에 정의된 코드에 접근할 수 있습니다. 이러한 동작을 렉시컬 스코핑이라고 합니다. 그러나 외부 함수는 내부 함수 내의 코드에 액세스할 수 없습니다.

foo의 내장함수인 bar에는 b, c라는 변수가 없으니까 부모 함수, 그리고 계속해서 전역 스코프까지 가서 조회를 하게 됩니다. 이렇게 함수가 정의된 실행 컨텍스트 스코프를 탐색하고, 호출된 변수와 함수를 확인하는 개념을 스코프 체인이라고 하고 스코프 체인은 단방향으로 동작하기 때문에 전역 스코프에서는 반대로 함수 안에 변수를 가져올 수 없습니다. 

 

 

3. this 키워드에 대한 값 설정 

자바스크립트에서 `this` 키워드는 이 스코프가 어느 실행 컨텍스트에 속하는지를 말합니다. 위에서 스코프 체인이 만들어지면, 자바스크립트 엔진에 의해서 `this`가 초기화됩니다. 

 

전역 실행 컨텍스트에서의 `this`는 전역 객체를 나타냅니다. 우리가 잘 알고 있는 window 객체죠.

함수 실행 컨텍스트에서는 `this` 객체를 생성하지 않고, 그 함수가 정의된 환경의 객체에 접근합니다. 

 

실행 단계 ( Execution Phase ) 

이 단계는 실제 코드 실행이 시작되는 단계입니다.

변수 객체에는 정의되지 않은 값을 가진 변수가 포함되어 있었습니다. 정의되지 않은 값으로는 작업할 수 없기 때문에 이 시점에서 코드를 실행하면 오류가 반환될 수밖에 없습니다. 자바스크립트 엔진은 현재 실행 컨텍스트에서 코드를 한 번 더 읽은 변수의 실제 값으로 변수 객체를 업데이트합니다. 그런 다음 파서에 의해 코드가 파싱되고 실행 가능한 바이트 코드로 변환되어 최종적으로 실행됩니다.

 

생성단계 -> 실행단계

 

 

실행 스택 ( 콜 스택 ) 

콜스택은 스크립트 생명 주기 동안 만들어진 실행 컨텍스트를 추적합니다. 자바스크립트는 싱글 스레드 언어로써, 한번에 하나의 작업만 실행되기때문에 다른 함수, 이벤트가 발생하면 각 이벤트에 대한 실행 컨텍스트가 생성되고 이게 스택으로 쌓이는데 이를 콜 스택이라고 부릅니다.

 

 

예시코드
콜스택 시나리오

1. 전역 실행 컨텍스트에 전역변수1, 2가 선언 및 할당이 됩니다. 그리고 함수 1,2 또한 정의됩니다.

2. 함수 1이 호출이 됩니다. 콜스택에 함수1이 추가됩니다. 로컬 변수 선언 및 할당 console.log()가 실행됩니다.

3. 함수 1에서 내장함수 1이 실행됩니다.  함수1은 멈추고 내장함수 1 스택이 쌓이게 됩니다. 그리고 console.log()가 실행됩니다.

4. 내장함수 1 코드 실행이 끝나서 POP 됩니다. 

5. 함수 1 코드 실행이 끝나서 POP이 되고 바로 함수 2 가 실행이 되어서 콜스택에 쌓이게 됩니다. console.log()가 실행됩니다.

6. 함수 2 코드 작업이 끝났기 때문에 해당 콜스택은 POP이 됩니다. 

 

 

참조

https://www.youtube.com/watch?v=RxaiFq2krAA

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

https://ui.dev/