실행 컨텍스트 (Execution Context)는 scope, hoisting, this, function closure 등의 동작원리를 담고 있는 자바스크립트의 핵심 원리다.
ECMAScript 스펙에 따르면 실행 컨텍스트를 실행가능한 코드를 형상화 하고 구분하는 추상적인 개념 이라고 정의한다. 쉽게 말하자면 실행 컨텍스트는 실행 가능한 코드가 실행되기 위해 필요한 환경 이라고 말할 수 있겠다. 여기서 말하는 실행 가능한 코드는 아래와 같다.
전역코드: 전역 영역에 존재하는 코드
Eval 코드 : eval 함수로 실행되는 코드
함수 코드: 함수 내에 존재하는 코드
일반적으로 실행 가능한 코드는 전역 코드와 함수내 코드이다.
자바스크립트 엔진은 코드를 실행하기 위하여 실행에 필요한 여러가지 정보를 알고 있어야 한다. 실행에 필요한 여러가지 정보란 아래와 같은 것드리 있다.
변수: 전역변수, 지역번수. 매개변수. 객체의 프로퍼티
함수 선언
변수의 스코프
this
이와 같이 실행에 필요한 정보를 형상화하고 구분하기 위해 자바스크립트 엔진은 실행 컨텍스트를 물리적 객체의 형태로 관리한다.
- 컨트롤이 실행 가능한 코드로 이동하면 논리적 스택 구조를 가지는 새로운 실행 컨텍스트 스택이 생성된다. 스택은 LIFO(Last In First Out)의 구조를 가지는 나열구조이다.
- 전역코드로 컨트롤이 진입하면 전역 실행 컨텍스트가 생성되고 실행 컨텍스트 스택에 쌓인다. 전역 실행 컨텍스트는 애플리케이션이 종료될 때까지 유지된다.
- 함수를 호출하면 해당 함수의 실행 컨텍스트가 생성되며 직전에 실행된 코드 블록의 실행 컨텍스트 위에 쌓인다.
- 함수 실행이 끝나면 해당 함수의 실행 컨텍스트를 파기하고 직전의 실행 컨텍스트에 컨트롤을 반환한다.
실행 컨텍스트의 3가지 객체
실행 컨텍스트는 실행 가능한 코드를 형상화하고 구분하는 추상적인 개념이지만 아래의 3가지 프로퍼티를 소유한다.
Variable Object {vars,function,declarations,arguments...}
Scope chain [Variable object + all parent scopes]
thisValue Context Object
Variable Object(VO / 변수객체_
실행 컨텍스트가 생성되면 자바스크립트 엔진은 실행에 필요한 여러 정보들을 담을 객체를 생성한다. 이를 VO 라고 한다. VO는 코드가 실행될 떄 엔진에 의해 참고되며 코드에서 접근할 수 없다.
VO는 아래의 정보를 담는 객체이다.
변수
매개변수와 인수 정보
함수선언(함수 표현식은 제외)
VO가 가리키는 객체는 아래와 같다.
전역 컨텍스트의 경우
VO는 유일하며 최 상위에 위치하고 모든 전역 변수, 전역 함수 등을 포함 하는
전역 객체 (Global Object / GO)를 가리킨다. 전역 객체는 선언된 전역 변수와 전역 함수를 프로퍼티로 소유한다.
함수 컨텍스트의 경우
Variable Object는 Activation Object(AO/활성 객체)를 가리키며 매개변수와 인수들의 정보를 배열의 형태로 담고 있는 객체인 arguments object가 추가된다.
Scope Chain (SC)
스코프체인은 일종의 리스트로서 전역 객체와 중첩된 함수의 스코프의 참조를 차례로 저장하고 있다. 스코프 체인은 해당 전역 또는 함수가 참조할 수 있는 변수, 함수 선언 등의 정보를 담고 있는 전역 객체(GO)또는 활성 객체 (AO)의 리스트를 가리킨다.
스코프 체인은 식별자 중에서 전역객체를 제외한 객체의 프로퍼티가 아닌 식별자, 즉 변수를 검색하는 메커니즘이다. 식별자 중에서 변수가 아닌 객체의 프로퍼티를 검색하는 매커니즘은 프로토타입 체인이다 <
엔진은 스코프 체인을 통해 렉시컬 스코프를 파악한다. 함수가 중첩 상태일 때 하위함수 내에서 상위함수의 스코프와 전역 스코프까지 참조할 수 있는데 이것은 스코프 체인을 검색을 통해 가능하다.
this value
this 프로퍼티에는 this 값이 할당된다. this에 할당되는 값은 함수 호출 패턴에 의해 결정된다.
실행 컨텍스트의 생성과정
전역 코드에의 진입
컨트롤이 실행 컨텍스트에 진입하기 이전에 유일한 전역 객체가 생성된다. 전역 객체는 단일 사본으로 존재하며 이 객체의 프로퍼티는 코드의 어떠한 곳에서도 접근할 수 있다. 초기 상태의 전역 객체에는 빌트인 객체와 BOM, DOM이 설정되어 있다.
전역 객체가 생성된 이후, 전역 코드로 컨트롤이 진입하면 전역 실행 컨텍스트가 생성되고 실행 컨텍스트 스택에 쌓인다.
그리고 이후 이 실행 컨텍스트를 바탕으로 이하의 처리가 실행된다.
1. 스코프 체인의 생성과 초기화
2. Variable Instantiation(변수 객체화)실행
3. this value 결정
스코프 체인의 생성과 초기화
실행 컨텍스트가 생성된 이후 가장 먼저 스코프 체인의 생성과 초기화가 실행된다. 이떄 스코프 체인은 전역 객체의 레퍼런스를 포함하는 리스트가 된다.
변수 객체화 실행
스코프 체인의 생성과 초기화가 종료하면 변수 객체화가 실행된다
Variable Instantiation은 변수 객체화는 Variable Object( 변수객체)에 프로퍼티와 값을 추가하는 것을 의미한다.
전역 코드의 경우 Variable Object는 Global Object를 가리킨다.
Variable Instantiation(변수 객체화)는 아래의 순서로 Variable Object에 프로퍼티와 값을 set 한다.
1. (Function Code인 경우)매개변수가 VO의 프로퍼티로, 인수가 값으로 설정된다.
2. 대상 코드 내의 함수 선언(함수 표현식 제외)을 대상으로 함수명이 VO의 프로퍼티로, 생성된 함수 객체가 값으로 설정된다.(함수 호이스팅)
3. 대상 코드 내의 변수 선언을 대상으로 변수명이 VO의 프로퍼티로 undefined가 값으로 설정된다 (변수 호이스팅)
####함수의 선언 처리
함수선언은 선언된 함수명이 VO(전역 코드인 경우 GO)의 프로퍼티로, 생성된 함수 객체가 값으로 설정된다.
생성된 함수 객체는 [[Scopes]] 프로퍼티를 가지게 된다 [[Scopes]]프로퍼티는 함수 객체만이 소유하는 내부 프로퍼티로서 함수 객체가 실행되는 환경을 가리킨다.
내부 함수의 [[Scopes]] 프로퍼티는 자신의 실행 환경과 자신을 포함하는 외부 함수의 실행 환경과 전역 객체를 가리키는데 이 떄 자신을 포함하는 외부 함수의 실행 컨텍스트가 소멸하여도 [[Scopes]] 프로퍼티가 가리키는 외부 함수의 실행환경은 소멸하지 않고 참조할 수 있다. 이것이 클로저이다.
함수 선언식의 경우, 선언문 이전에 함수를 호출할 수 있다. 이러한 현상을 함수호이스팅 (Function Hoisting)이라 한다.
변수 x의 선언처리
변수 선언은 선언된 변수명이 VO의 프로퍼티로 undefined가 값으로 설정된다
선언단계: 변수 객체에 변수를 등록한다. 이 변수 객체는 스코프가 참조할 수 있는 대상이 된다.
초기화단계: 변수 객체에 등록된 변수를 메모리에 할당한다. 이 단계에서 변수는 undefined로 초기화된다.
할당단계: undefined로 초기화된 변수에 실제값을 할당한다.
var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다.
따라서 변수 선언문 이전에 변수에 접근하여도 VO에 변수가 존재하기 때문에 에러가 발생하지 않고 undefined를 반환한다 이러한 현상을 변수 호이스팅(Variable Hoisting)이라 한다.
this value 결정
변수 선언 처리가 끝나면 다음은 this value가 결정된다. this value가 결정되기 이전에 this는 전역 객체를 가리키고 있다가 함수 호출 패턴에 의해 this에 할당되는 값이 결정된다
전역 컨텍스트(전역 코드)의 경우, VO, 스코프 체인, this 값은 언제나 전역 객체이다.
전역 코드의 실행
변수 값의 할당
함수의 실행
전역 코드의 함수가 실행되기 시작하면 새로운 함수 실행 컨텍스트가 생성된다.
함수 실행 컨텍스트로 컨트롤이 이동하면 전역 코드와 마찬가지로
1.스코프 체인의 생성과 초기화, 2.Variable Instantiation실행, 3.this value 결정
스코프 체인의 생성과 초기화
함수 코드의 스코프 체인의 생성과 초기화는 우선 AO에 대한 참조를 스코프 체인의 선두에 설정하는 것으로 시작된다.
AO는 우선 arguments 프로퍼티의 초기화를 실행하고 그후 VI가 실행된다.
그후 Caller(전역 컨텍스트)의 스코프 체인이 참조하고 있는 객체가 스코프 체인에 push된다.
VI 실행
Function Code의 경우 스코프 체인의 생성과 초기화에서 생성된 AO를 VO 로서
VI가 실행된다.
this value 결정
변수 선언 처리가 끝나면 다음은 this value가 결정된다 this에 할당되는 값은 함수 호출 패턴에 의해 결정된다. 내부 함수의 경우 this의 value는 전역 객체이다.
함수의 실행
변수 값의 할당
함수 실행
함수가 실행되기 시작하면 새로운 컨텍스트가 생성된다.
1. 스코프 체인의 생성과 초기화, 2.VI실행, 3.this value 결정이 순차적으로 실행된다.
'FrontEnd > JavaScript' 카테고리의 다른 글
[JavaScript] 몇가지 트릭들 (0) | 2022.06.07 |
---|---|
[JavaScript] this (0) | 2022.06.07 |
[JavaScript] 프로토타입 (0) | 2022.06.07 |
프론트엔드 공부 로드맵 (0) | 2022.06.07 |
[JavaScript] 프로퍼티와 내부메서드 (0) | 2022.06.07 |