함수가 실행되는 영역이자 묶음입니다. 함수 코드를 실행하고 그 결과를 저장합니다.(변수 값, 다른 함수를 통한 리턴값 등) 스펙상의 사양으로 엔진이 컨트롤하며 개발자가 임의적인 조종은 불가능합니다.
function music(title) { var musicTitle = title; }; music("음악");
music("음악")으로 함수를 호출하면 엔진은 실행 콘텍스트를 생성하고 실행 콘텍스트 안으로 이동합니다. 준비 단계, 초기화 단계, 코드 실행 단계의 과정을 거쳐 실행합니다. 앞에선 초기화 단계와 코드 실행의 단계에 초점을 맞추었다면 이번 장에선 준비 단계에 대하여 이야기 해볼까 합니다.
Execution Context 는 실행 가능한 코드를 만났을 때 생성됩니다. 함수 코드, 글로벌 코드, eval 코드 3가지 유형의 코드를 실행 가능합니다. 각각의 코드 유형은 실행 콘텍스트에서 처리 방법과 실행 환경이 다르기 때문에 구분하여 이해해야 합니다.
실행 콘텍스트 상태를 위한 오브젝트로 실행 콘텍스트 안에 생성됩니다.
실행 콘텍스트(EC): { 렉시컬 환경 컴포넌트(LEC): { }, 변수 환경 컴포넌트(VEC): { }, this 바인딩 컴포넌트(TBC): { } }
함수와 변수의 식별자 해결을 위한 환경 설정하는 것을 의미합니다. 함수 초기화 단계에서 해석한 함수와 변수를 {name: value}
형태로 저장합니다. 이를 통하여 이름으로 함수와 변수를 검색(식별자 해결)할 수 있게 됩니다. 또한, 함수 밖의 함수와 변수를 참조 환경 설정하여 함수 밖의 함수와 변수를 사용할 수 있게 됩니다.
메모리 안에 실행 콘텍스트가 올라와 있는 상황에서 이동없이 모두 한 콘텍스트 안에서 처리하는 것을 목적으로 합니다.
function, with, try-catch에서 렉시컬 환경 컴포넌트 가 생성됩니다.
컴포넌트 구성
- 환경 레코드
ER: Environment Record- 외부 렉시컬 환경 참조
OLER: Outer Lexical Environment Reference
실행 콘텍스트(EC): { 렉시컬 환경 컴포넌트(LEC): { 환경 레코드(ER): { point:100 }, 외부 렉시컬 환경 참조(OLER): { title:"책", getTitle: function() {} } } }
따라서, 하나의 콘텍스트의 관점에 맞추어 코딩을 구성하다 보면 엔진의 처리가 심플해지므로 효율성이 높습니다.
스코프와 실행 중인 함수가 Context(묶음) 형태이기에 스코프의 변수와 함수를 별도의 처리 없이 즉시 사용할 수 있습니다. 실행 콘텍스트에서 함수 안과 밖의 함수, 변수를 사용할 수 있으므로 함수와 변수를 찾기 위해 실행 콘텍스트를 벗어나지 않아도 됩니다.
실행 콘텍스트 초기화 단계에서 렉시컬 환경 컴포넌트와 같게 설정합니다. 초기값을 복원할 때 사용하기 위함입니다. 함수 코드가 실행되면 실행 결과를 렉시컬 컴포넌트에 설정합니다. 할당을 통해 초기값이 변하게 되므로 이를 유지하기 위한것입니다. with문에서 주로 사용합니다.
var base = 200; function getPoint(bonus) { var point = 100; return point + base + bonus; }; console.log(getPoint(70)); // 370
[[Scope]]
에 글로벌 오브젝트 설정실행 콘텍스트(EC): { 렉시컬 환경 컴포넌트(LEC) = { 환경 레코드(ER): {} }, 변수 환경 컴포넌트(VEC): {}, this바인딩 컴포넌트(TBC): {} }
실행 콘텍스트(EC): { 렉시컬 환경 컴포넌트(LEC) = { 환경 레코드(ER): {}, 외부 렉시컬 환경 참조(OLER): { base: 200 } }, 변수 환경 컴포넌트(VEC) : {}, this바인딩 컴포넌트(TBC) : {} }
[[Scope]]
를 참조(설정)합니다.실행 콘텍스트(EC): { 렉시컬 환경 컴포넌트(LEC) = { 환경 레코드(ER): { bonus: 70, point: undefined }, 외부 렉시컬 환경 참조(OLER): { base: 200, } }, 변수 환경 컴포넌트(VEC): {}, this바인딩 컴포넌트(TBC): {} }
var base = 200; function getPoint(bonus) { var point = 100; return point + base + bonus; }; console.log(getPoint(70)); // 370
function book() { function get() { return point; }; var point = 123; return get(); }; console.log(book());
[[scope]]
에 글로벌 오브젝트 설정[[scope]]
를 외부 렉시컬 환경 참조에 설정(참조)합니다.실행 콘텍스트(EC): { 렉시컬 환경 컴포넌트(LEC) = { 환경레코드(ER): { get: function 오브젝트, point: undefined; }, 외부 렉시컬 환경 참조(OLER): {} }, 변수 환경 컴포넌트(VEC): {}, this 바인딩 컴포넌트(TBC): {} }
[[Scope]]
에 get 스코프를 설정합니다.실행 콘텍스트(EC): { 렉시컬 환경 컴포넌트(LEC) = { 환경레코드(ER): {}, 외부 렉시컬 환경 참조(OLER): { point: 123 } }, 변수 환경 컴포넌트(VEC): {}, this 바인딩 컴포넌트(TBC): {} }
실행 콘텍스트(EC): { 렉시컬 환경 컴포넌트(LEC): { 환경 레코드(ER): { 선언적 환경 레코드(DER): { point: 123 }, 오브젝트 환경 레코드(OER):{} }, 외부 렉시컬 환경 참조(OLER): {} }, 변수 환경 컴포넌트(VEC): {}, this 바인딩 컴포넌트(TBC): {} }
환경 레코드를 구분하는 이유는 기록 대상에 따라 다르기 때문입니다.
선언적 환경 레코드
오브젝트 환경 레코드
실행 콘텍스트(EC): { 글로벌 환경(GE): { 환경 레코드(ER): { 오브젝트 환경 레코드: 글로벌 오브젝트 }, 외부 렉시컬 환경 참조(OLER): null } }
var obj = {point: 100}; obj.getdPoint = function() { return this.point; }; obj.getPoint();
실행 콘텍스트(EC): { 렉시컬 환경 컴포넌트(LEC): { 환경 레코드(ER): { 선언적 환경 레코드(DER): {}, 오브젝트 환경 레코드(OER):{} }, 외부 렉시컬 환경 참조(OLER): {} }, 변수 환경 컴포넌트(VEC): {}, this 바인딩 컴포넌트(TBC): { point: 100, getPoint: function(){} } }
function one(){ two(); console.log(1); }; function two(){ three(); console.log(2); }; function three(){ console.log(3); }; one(); // 3 // 2 // 1
함수가 호출되면 3개의 파라미터 값을 실행 콘텍스트로 넘겨줍니다.
- 함수를 호출한 오브젝트
- 함수 코드
- 호출한 함수의 파라미터 값
호출한 함수에서 넘겨 준 파라미터 값을 호출 된 함수의 파라미터 작성 순서에 맞춰 값을 매핑하는 것.
[[FormalParameters]]
에 작성된 이름에 값[[FormalParameters]]
var obj = {}; obj.getTotal = function(one, two) { return one + two; } console.log(obj.getTotal(11,22,77)); // 33
["one", "two"]
형태입니다.[[FormalParameters]]
는 function 오브젝트를 생성할 때 설정합니다.var obj = {}; obj.getTotal = function(one, two) { var one; console.log(one + two); two = 77; console.log("two:"+two); } obj.getTotal(11, 22);
var obj = {}; obj.getTotal = function(one, two, two) { console.log(one + two); }; obj.getTotal(11, 22, 55); // 66
실행 콘텍스트(EC): { 렉시컬 환경 컴포넌트(LEC) = { 환경레코드(ER) : { 선언적 환경 레코드(DER) : { argument : {one: 11, two: 55} }, 오브젝트 환경 레코드(OER) : {} }, 외부 렉시컬 환경 참조(OLER) : { } }, 변수 환경 컴포넌트(VEC) : {}, this 바인딩 컴포넌트(TBC) : { obj : {} } }
아.. 쉽지 않은 실행컨텍스트입니다요.. 정리 굳입니다🙆♂️