JavaScript 실행 컨텍스트

김철회·2022년 8월 2일
0
post-thumbnail

자바스크립트의 실행 컨텍스트 알아보기!

실행 컨텍스트란?

작성한 코드를 실행하기 위해서 자바스크립트 엔진은 코드 실행을 위한 여러 정보들을 알고 있어야 한다. 선언한 변수, 함수와 같은 식별자, 변수의 유효범위(스코프), this와 같은 정보들이 있다.
즉, 실행 컨텍스트는 코드가 실행 되기 전에, 작성한 코드를 실행하기 위해 필요한 정보들을 가진 범위를 추상화, 형상화하고 구분하여 객체 형태로 나타낸 것을 말한다.

자바스크립트 엔진이 코드 실행을 위해 필요로 하는 정보들

  1. 변수
  2. 함수
  3. 변수의 유효범위
  4. this

실행 컨텍스트의 종류와 실행 컨텍스트의 관리와 동작

먼저 알아두어야 하는 실행 컨텍스트의 종류

global execution context(전역 실행 컨텍스트)
기본 실행 컨텍스트로 함수 내부에 없는 코드들은 global execution context에서 실행된다.
이 과정에서 전역 객체인 1)window object가 생성된다. 그리고 이때 2)this가 window객체를 가리킨다.

function execution context(함수 실행 컨텍스트)
자바스크립트 엔진은 함수가 호출 될 때마다 호출된 함수를 위한 execution context를 생성한다. 그리고 모든 함수는 호출되는 시점에 자신만의 execution context를 가진다.
또한, 자바스크립트 엔진은 코드를 실행하기 위해 처음 한 번만 global execution context를 생성하고 함수는 호출될 때마다 함수를 위한 execution context를 생성한다.

eval function execution context
eval 함수 내에서 실행되는 코드도 함수이기 때문에 실행 컨텍스트를 갖는다. 하지만 보안상의 이유로 eval은 잘 사용되지 않는다고 한다.

call stack(호출 스택)
call stack은 코드가 실행되면 execution context를 저장하는 곳이다. 기본적으로 LIFO(last in, first out)의 구조 형태이다. 자바스크립트 엔진은 코드가 실행되면 global execution context를 생성하고 이를 call stack에 먼저 push한다. 그리고 함수가 호출되면 function execution context를 생성하고 이를 다시 call stack에 저장된 global execution context 위에 저장한다.
그 다음에, 해당 함수가 종료되면 call stack에서 함수가 제거되고, 코드를 작성한 순서대로 그 다음에 호출되는 함수가 있다면 그 함수가 call stack에 저장된다.

다음의 코드가 call stack에서 저장되고 제거되는 과정을 그림으로 살펴보자!

var x = 'x';

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

  1. 자바스크립트 엔진은 코드를 실행하기 위해 먼저 global execution context를 call stack에 저장했다.
  2. 함수가 호출될 때마다 함수 자신만의 function execution context가 생성이 되고 여기서는 foo가 먼저 호출됐기 때문에 foo의 context가 생성되어 call stack에 저장되었다.
  3. foo가 호출되고 foo 내부의 bar가 호출되는 것을 확인하면 다시 bar를 위한 function execution context가 생성된다. 그리고 foo 위에 bar가 쌓인다.
  4. bar가 실행이 되면서 콘솔창에 x+y+z의 값을 띄운다. 그러면 bar가 종료된다. 그렇게 bar는 call stack에서 제거된다.
  5. bar가 종료되고 foo도 잇따라 종료되면서 call stack에서 제거된다.
  6. 모든 코드의 실행이 종료되면 call stack에서 global execution context도 제거된다.

결론
자바스크립의 엔진은 코드가 실행될 때, global execution context를 call stack에 저장되고 작성한 코드를 위에서부터 순서대로 읽으면서 funciton 호출을 만날 때마다 function execution context를 call stack에 추가하고 제거하는 과정을 거친다.

실행 컨텍스트는 어떻게 생성되는가!

엔진이 실행 컨텍스트를 관리하고 저장하는지는 알았는데, 실행 컨텍스트는 어떻게 생성되는지도 같이 알아야 한다.
크게 Creation과 Execution phase로 나뉜다.

Creation Phase

실행 컨텍스트는 생성 단계에서 먼저 생성이 되는데, 이때 두 가지가 일어난다.
1) Lexical Environment
2) Variable Environment 가 생성된다.

lexical Environment
함수와 변수와 같은 식별자를 정의하는데 사용하는 객체라고 생각하는 게 좋다. 다른 정의는 머리가 아주 아팠다..
다시, lexical environment에는 3가지 구성요소가 있다.
1) Environment Records

  • lexical environment안에서 함수와 변수 선언을 저장하는 곳이다.
  • 전역코드의 lexical environment의 경우, 변수와 함수 선언과는 다른 전역 객체도 저장한다.

2) Reference to the outer environment

  • 외부 환경에 대한 참조는 외부에 있는 Lexical environment환경에 접근할 수 있다는 것이다. 자바스크립트 엔진은 내부 함수에서 사용되는 변수가 내부에 없다면 그 상위의 스코프에서 변수를 찾을 수 있다는 것을 의미한다.

3) this binding

  • this의 값에 대한 할당이 여기서 이루어진다. 전역 실행 컨텍스트의 this는 전역객체(window)인데, 함수 실행 컨텍스트의 this는 this가 호출되는 방식에 따라 다르다. 객체에 의해서 호출되면 해당 객체로 설정되고 / 그렇지 않으면 window를 가르키거나 / strict mode에서는 undefined 이다.

Variable environment
lexical environment와 기본적으로 같지만, var로 선언된 변수만 저장한다. 그외의 나머지인 let과 const, 함수 선언은 모두 lexical environment에 저장된다.

Execution Phase

이 페이즈에서 마침내, 변수의 선언에 대한 값 할당과 함께 코드가 실행된다.

예제와 함께 살펴보도록 하자!

let a = 20;
const b = 30;
var c;

function x(e, f){
	var g = 20;
	return e * f * g;
}
c = x(1, 2);
  1. 위의 코드가 실행이 되면 자바스크립트 엔진은 실행 컨텍스트의 과정과 동작에서 본 것 처럼
  • global execution context를 만들고
  • 전역 스코프에 있는 함수와 let, const는 lexical environment로 저장
  • var는 variableEnvironment로 저장한다.
  1. Execution phase에서 실행되는 동안 각각의 변수에 실제 지정한 값들이 할당된다.

  2. x함수가 호출되면

  • function execution context가 생성되고 call stack에 쌓인다.
  • 이때, function execution context가 생성되면서 함수 내의 var는 해당 function execution context의 variableEnvironment로 저장된다.(컨텍스트가 함수 호출이 되면 만들어 지기 때문에 같은 creation, execution 과정을 거치는 것이다)
  1. 다시 함수 실행 컨텍스트가 execution phase에 들어오면서 변수에 지정한 값들이 할당된다.

  2. 함수 실행이 완료되면 반환된 값을 내부에 저장하고 반환된 내부 값이 global lexical environment에 업데이트 되고 callstack에서 해당 함수들이 제거된다.

profile
안녕하세요!

0개의 댓글