실행 컨텍스트와 스코프

실행 컨텍스트와 스코프

실행 컨텍스트란?

ECMAScript의 정의를 살펴보면 실행 가능한 코드를 형상화하고 구분하는 추상적인 개념이라고 설명하고 있다.
즉 실행 가능한 자바스크립트 코드 블록이 실행되는 환경이라고 할 수 있다. 실행 가능한 코드에는 전역 코드, eval() 코드, 함수 코드가 있다.

우리는 오늘 한가지 예제를 통해 콜 스택부터 실행 컨텍스트, 스코프가 어떻게 설계되는 지에 대해 살펴보도록 하겠다.

참조사이트
var x = 'xxx';

function foo () {
  var y = 'yyy';

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

이 코드에서는 스택이 쌓이고 소멸하게 된다.

stack

  1. 실행 가능한 코드가 새로운 실행 컨텍스트 스택으로 생성된다. 이때는 후입선출(LIFO)로 진행된다.
  2. 전역 실행 컨텍스트는 처음에 만들어져 컨텍스트가 끝날 때까지 유지된다
  3. 함수 호출 시 스택이 쌓인다.
  4. 함수 호출이 끝나면 실행 컨텍스트를 파기하고 직전 실행 컨텍스트의 컨트롤을 반환한다.

실행 컨텍스트 생성과정

  1. 전역 컨텍스트의 경우
    전역에 선언된 전역변수와 전역 함수를 객체로 갖는다.

go

  1. 함수 컨텍스트의 경우
    활성 객체를 가리키며 매개변수와 인수들의 정보를 가지고 있는 arguments객체가 추가된다.

ao

순서로는 우선 활성 객체를 생성한다. 그 후 arguments 객체를 생성한다. 이 떄 활성객체는 arguments 프로퍼티로 arguments 객체를 참조하게 된다. 그 후 스코프의 정보를 생성한다. 연결 리스트와 유사한 형태로 만들어지며 [[scope]] 프로퍼티로 참조된다. 그 후 변수를 생성한다. 주의할 점은 생성과 초기화만 진행할 뿐, 실행되기 전까지는 할당이 이루어지지 않는다는 것이다. 마지막으로 this를 할당하는 데 함수 호출 패턴에 따라 this가 참조하는 객체가 정해진다.

  • 전역 코드 진입

전역 객체가 생성되면 전역 코드로 컨트롤이 진입하여 전역 실행 컨텍스트가 생성되고 실행 컨텍스트가 쌓인다.

전역코드

  • 스코프 체인 생성 및 초기화

이 때 스코프체인은 전역 객체 레퍼런스를 포함한다.

스코프체인

  • 변수 객체화

변수 객체화

여기선 매개변수가 변수 객체의 프로퍼티로 인수가 값으로 설정된다. 그 후 코드 내 함수 선을 대상으로 변수 객체가 프로퍼티로, 생성된 함수 객체가 값으로 설정되며 함수 호이스팅이 발생한다. 그 다음 대상 코드 대상으로 변수 명이 변수 객체의 프로퍼티로 undefined가 값으로 설정된다. 이를 변수 호이스팅이라고 한다.

이후 위 코드의 함수 foo가 처리된다. 함수 foo가 프로퍼티로 생성된 함수 객체가 값으로 지정된다. 이 때 생성된 함수 객체는 [[scope]] 프로퍼티를 가진다. 이 때 [[scope]] 프로퍼티는 자신의 실행환경을 가지고 자신을 포함하는 외부 함수와 실행 환과 전역 객체를 가리킨다. 또한 자신을 포함하는 외부 함수의 실행 컨텍스트가 소멸하여도 [[scope]] 프로퍼티가 가리키는 외부함수 실행환경을 참조할 수 있는데 이것이 클로저다.

이후 변수 x를 처리하는데 var 변수는 선언과 초기화가 한 번에 이루어진다. 그 후 this value를 정한다. 이전에는 this가 전역 객체를 가리키다가, 함수 호출 패턴에 이해 this가 정해진다.

this까지

함수 호출 패턴