2. 실행 컨텍스트

gugyeoj1n·2022년 4월 22일
0

자바스크립트

목록 보기
2/9

근무 끝나고 그냥 자려고 했는데 하나만 더 보고 자야겠다.


실행 컨텍스트 Execution Context. Context는 문맥, 맥락, 환경 등의 뜻이 있는데, 여기서는 코드의 배경이 되는 조건 또는 환경을 의미한다. 즉 실행 컨텍스트란 코드를 실행하는데 필요한 배경이 되는 조건이라고 한다. 여기서 코드는 동일한 조건을 갖는 코드 덩어리를 가리킨다. 자바스크립트에서는 전역 공간, 함수, eval, module 이 해당된다.

eval() 은 문자로 표현된 자바스크립트 코드를 실행해 주는 함수인데, 실행할 때 caller의 권한을 갖기 때문에 굉장히 위험하다고 한다 ! ! 사실 쓸 일이 있을까 싶긴 하다

전역 공간과 모듈은 거대한 하나의 함수로 봐도 무방하니, 결과적으로 자바스크립트 안에서 독립된 코드 덩어리는 함수라고 얘기할 수 있다. 함수 속에 들어가는 if, for, while 등의 조건문 / 반복문은 별개의 실행 컨텍스트를 생성하지 않는다. 물론 ES6에서 블록 스코프 개념과 let, const가 등장했지만, 실행 컨텍스트에 해당되지는 않는다. 나 때는 var밖에 없었는데

최종적으로 보자면 실행 컨텍스트함수를 실행할 때 필요한 조건, 환경 정보를 담은 객체이다.

var a = 1;

function outer() {
	console.log(a); // 1번째
    
    function inner() {
    	console.log(a); // 2번째
        var a = 3;
    }
    
    inner();
    
    console.log(a); // 3번째
}

outer();
console.log(a); // 4번째

이 코드를 갖고 실행 컨텍스트의 작동 원리를 살펴 보도록 하겠다.

1) 전역 컨텍스트가 열리고, 코드를 읽어나간다.

var a = 1;

function outer() { ... }

outer();

선언 부분들은 넘어가다가 함수를 실행하는 부분이 나왔다.

2) outer() 가 실행되면서 그 함수의 실행 컨텍스트가 열린다.

function outer() {
	console.log(a); // 1번째

첫번째로 만난 console.log(a) 를 실행한다.

	function inner() { ... }
    
    inner();

또 inner() 를 선언하는 부분은 넘기고, inner() 가 실행된다.

3) inner() 가 실행되면서 그 함수의 실행 컨텍스트가 열린다.

function inner() {
    	console.log(a); // 2번째
        var a = 3;
    }

두번째 console.log(a) 가 실행되었다.
inner() 함수가 종료되는 동시에 이 함수의 실행 컨텍스트는 닫히게 된다.

var a = 1;

function outer() {
	console.log(a); // 1번째
    
    function inner() {
    	console.log(a); // 2번째
        var a = 3;
    }
    
    inner();
    
    console.log(a); // 3번째
}

outer();
console.log(a); // 4번째

4) 실행이 끝난 함수의 실행 컨텍스트는 닫히고 다음 코드로 넘어간다.

inner(); 가 끝났으니 그 다음 코드인 세번째 console.log(a) 를 출력한다.
그럼 outer() 함수도 끝났으니 outer() 함수의 실행 컨텍스트가 닫힌다.

outer(); 밑에 있는 마지막 console.log(a) 가 실행되고, 모든 코드가 끝났으니 전역 컨텍스트도 닫히고 끝이 난다.


실행 컨텍스트의 순서를 보면 전역, outer(), inner() 순으로 열리고 inner(), outer(), 전역 순으로 닫혔다. 주요 자료구조 중 하나인 스택과 같은 구조를 갖고 있다. 실제로 코드 실행에 관여하는 스택을 Call Stack 콜스택이라고 한다. 현재 어떤 함수가 동작 중인지, 다음에 어떤 함수가 호출될 예정인지 등을 제어하는 자료구조이다.

간단하게 [ 를 콜스택이라고 한다면, 위의 코드에서는

1) [ 전역
2) [ 전역 outer()
3) [ 전역 outer() inner()
4) [ 전역 outer()
5) [ 전역
6) [

순으로 컨텍스트들이 콜스택에 들어왔다 나간 셈이다.

그럼 실행 컨텍스트에는 무슨 내용이 들어있을까?


하나의 함수를 담당하는 실행 컨텍스트에는 VariableEnvironment, LexicalEnvironment, Thisbinding 이 존재한다.
VariableEnvironment 와 LexicalEnvironment 는 현재 환경과 관련된 식별자 정보를 담는다. VariableEnvironment 는 오직 식별자 정보를 수집하는 용도로만 사용되고, LexicalEnvironment 는 각 식별자에 담긴 데이터를 추적하는 용도로 쓰인다. 컨텍스트 내부의 코드가 실행되는 동안 변수의 값에 변화가 생기면 그 값은 LexicalEnvironment에 실시간으로 반영된다. 이 둘에게는 실시간으로 바뀌는지 안 바뀌는지의 차이밖에 없으므로 LexicalEnvironment만 깊게 살펴봐도 문제가 없을 것이다. 라고 한다

LexicalEnvironment의 뜻은 어휘적 / 사전적 환경이다. 쉽게 말해 실행 컨텍스트의 환경 정보를 담은 Dictionary 이다. key에 식별자, value에 값이 들어가는 셈이다. 이 LE (편의상 줄여서 쓰겠다) 에는 현재 실행 컨텍스트의 내부 식별자 정보를 담는 environmentRecord와 외부 환경을 참조하는 정보를 담는 outerEnvironmentReference 가 들어있다.
environmentRecord는 실행 컨텍스트가 처음 실행될 때 현재 문맥의 식별자 정보를 수집한다. 이 과정은 선언문을 코드 맨 위로 끌어올리는 호이스팅 Hoisting 과 같다고 볼 수 있다. 물론 실제로 코드 구조가 바뀌진 않는다.
outerEnvironmentReference 부터는 내일 쓰겠다 왜냐고? 오늘 연등이 11시까지거든

0개의 댓글