3/ 실행 컨텍스트와 스코프

3/ 실행 컨텍스트와 스코프

목차

프론트엔드 개발자를 위한 자바스크립트 프로그래밍 책을 참고하여 정리합니다. 오류가 있다면 언제든지 댓글 남겨주세요.


1. 실행 컨텍스트

실행 컨텍스트(Execution Context)는 scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트의 핵심원리이다. ECMAScript 스펙에 따르면 실행 컨텍스트를 실행 가능한 코드를 형상화하고 구분하는 추상적인 개념이라고 정의한다. 즉, 실행 컨텍스트는 실행 가능한 코드가 실행되는 환경이라고 말할 수 있다.
실행 가능한 코드란

  • 전역코드 : 전역 영역에 존재하는 코드
  • 함수코드 : 함수 내에 존재하는 코드
  • Eval코드 : Eval 함수로 실행되는 코드

일반적으로는 전역코드와 함수코드.

자바스크립트 엔진은 코드를 실행하기 위해 실행에 필요한 여러가지 정보를 알고 있어야 한다.

  • 변수: 전역변수, 지역변수, 매개변수, 객체의 프로퍼티
  • 함수 선언
    • 함수 표현식은 호이스팅이 안되는 이유. (함수 표현식은 변수에 할당되는 방식이기 때문에)
  • 변수의 유효범위 (Scope)
  • this

자바스크립트 엔진은 실행 컨텍스트를 물리적 객체의 형태로 관리한다.


2. 실행 컨텍스트의 3가지 객체

객체의 형태를 가지며 아래의 3가지 프로퍼티를 소유한다.

  • Variable object
  • Scope chain
  • thisValue

2-1. Variable object (VO 변수객체)

변수나 함수의 실행 컨텍스트는 다른 데이터에 접근할 수 있는지, 어떻게 행동하는지를 규정합니다. 각 실행 컨텍스트에는 변수객체(variable object:VO)가 연결되어 있으며, 해당 컨텍스트에서 정의된 모든 변수함수는 이 객체에 존재한다. 코드로는 접근할 수 없다.

  • 변수
  • parameter arguments
    • parameter, 매개변수 : 함수 원형 작성시 사용되는 변수를 인자 (이름보다는 타입이 중요)
    • argument, 실행인자 : 코딩 중 함수 호출시 사용되는 변수 또는 실제 값을 인수
  • 함수 선언 (함수 표현식은 제외)

Variable Object는 실행 컨텍스트의 프로퍼티이기 때문에 값을 갖는데, 이 값은 다른 객체를 가리킨다.
전역 컨텍스트와 함수 컨텍스트가 가리키는 객체는 다르다. 함수에만 파라미터가 존재한다.

전역 컨텍스트인 경우

Variable Object는 전역 변수, 전역 함수 등을 포함하는 전역 객체(Global Object/GO)를 가리킨다. 전역변수와 전역함수는 전역 객체의 프로퍼티이다.

전역 컨텍스트란

  • 가장 바깥쪽에 존재하는 실행 컨텍스트이다.

  • ECMAScript를 구현한 환경에 따라 이 컨텍스트를 부르는 이름이 다르다.

    • 웹 ()
      • 전역컨텍스트 : window
      • 전역변수와 전역함수는 모두 window의 프로퍼티 및 메서드로 생성된다.
  • 전역컨텍스트는 애플리케이션이 종료될 때, 웹페이지를 나가거나 브라우저를 닫을 때까지 유지된다.

함수 컨텍스트인 경우

Variable Object는 Activation Object(AO/활성객체)를 가리키며 arguments object가 추가된다.
arguments object 매개변수와 인수들의 정보를 배열의 형태로 담고 있는 객체이다.
(이전 글에서 함수의 매개변수로 값이 전달될 때 arguments object에 들어간다고 했다. 전달한 값이 argument라고 생각하면 된다. arguments object: 함수 호출 시 전달된 인수들의 정보를 담고 있는 유사배열객체.)

실행컨텍스트 스택

1
2
3
4
5
6
7
8
9
10
11
12
var x = 'xxx';

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

function bar () {
var z = 'zzz';
console.log(x + y + z);
}
bar();
}
foo();
1. 컨트롤이 실행 가능한 코드로 이동하면 논리적 스택 구조를 가지는 새로운 실행 컨텍스트 스택이 생성된다. 스택은 LIFO(Last In First Out, 후입 선출)의 구조를 가지는 나열 구조이다. 2. 전역 코드(Global code)로 컨트롤이 진입하면 전역 실행 컨텍스트가 생성되고 실행 컨텍스트 스택에 쌓인다. 전역 실행 컨텍스트는 애플리케이션이 종료될 때(웹 페이지에서 나가거나 브라우저를 닫을 때)까지 유지된다. 3. 함수를 호출하면 해당 함수의 실행 컨택스트가 생성되며 직전에 실행된 코드블럭의 실행 컨텍스트 위에 쌓인다. 4. 함수 실행이 끝나면 해당 함수의 실행 컨텍스트를 파기하고 직전의 실행 컨텍스트에 컨트롤을 반환한다. ECMAScript 프로그램은 모두 이런 식으로 실행된다.

3. 스코프 체인 SC

스코프 체인은 일종의 리스트로서 중첩된 함수의 스코프의 레퍼런스를 차례로 저장하고 있는 개념이다.
즉, 현재 실행컨텍스트의 활성객체(AO)를 선두로하여 순차적으로 상위 컨텍스트의 AO를 가리키며 마지막 리스트는 전역 객체를 가리킨다.

스코프 체인의 목적은 실행 컨텍스트가 접근할 수 있는 모든 변수와 함수에 순서를 정의하는 것.

  • 함수가 중첩 상태일 때 하위함수 내에서 상위함수의 유효범위까지 참조할 수 있는데 이것는 스코프 체인을 검색하였기 때문이다.
  • 함수가 중첩되어 있으면 중첩될 때마다 부모 함수의 Scope가 자식 함수의 스코프 체인에 포함된다.
  • 함수 실행중에 변수를 만나면 그 변수를 우선 현재 Scope, 즉 Activation Object에서 검색해보고,
  • 만약 검색에 실패하면 스코프 체인에 담겨진 순서대로 그 검색을 이어가게 되는 것이다.

이것이 스코프 체인이라고 불리는 이유이다.

이와 같이 순차적으로 스코프 체인에서 변수를 검색하는데 결국 검색에 실패하면 정의되지 않은 변수에 접근하는 것으로 판단하여 Reference 에러를 발생시킨다.
스코프 체인은 [[scope]] 프로퍼티로 참조할 수 있다.


4. this value

this 프로퍼티에는 this 값이 할당된다. this에 할당되는 값은 함수 호출 패턴에 의해 결정되는데, 이는 Function 글에서 자세히 다루겠다.


5. 실행 컨텍스트의 생성과정

1
2
3
4
5
6
7
8
9
10
11
12
13
var x = 'xxx';`

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

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

foo();
  1. 전역 코드에 진입
    컨트롤이 실행 컨텍스트에 진입하기 이전에 유일한 전역 객체(Global Object)가 생성된다. 초기 상태의 전역 객체에는 빌트인 객체(Math, String, Array 등)와 BOM, DOM이 설정되어 있다.

참고링크

  1. http://poiemaweb.com/js-execution-context
  2. http://nerissa.tistory.com/entry/Parameter%EC%99%80-Argument%EC%9D%98-%EC%B0%A8%EC%9D%B4
  3. http://poiemaweb.com/js-function
📚