function music(title){
var musicTitle = title;
};
music("음악");
Exeuction Context
music("음악")으로 함수를 호출하면
실행 콘텍스트 실행 단계
Execution Context 생성 시점
실행 가능한 코드 유형
코드 유형을 본리한 이유
함수 코드
: 렉시컬 환경글로벌 코드
: 글로벌 환경eval 코드
: 동적 환경실행 콘텍스트(EC): {
렉시컬 환경 컴포넌트(LEC): { },
변수 환경 컴포넌트(VEC): { },
this 바인딩 컴포넌트(TBC): { },
}
실행 콘텍스트 상태를 위한 오브젝트
상태 컴포넌트 유형
렉시컬 환경 컴포넌트(LEC)
: Lexical Environment Component변수 환경 컴포넌트(VEC)
: Variable Environment Componentthis 바인딩 컴포넌트(TBC)
: This Binding Component함수와 변수의 식별자 해결을 위한 환경 설정
함수 초기화 단계에서 해석한
함수 밖의 함수와 변수 참조 환경 설정
실행 콘텍스트(EC): {
렉시컬 환경 컴포넌트(LEC): {
환경 레코드(ER): {
point: 100
},
외부 렉시컬 환경 참조(OLER): {
title: "책",
getTitle: function(){}
}
}
}
렉시컬 환경 컴포넌트 생성
컴포넌트 구성
환경 레코드(ER)
: Environment Record외부 렉시컬 환경 참조(OLER)
: Outer Lexical Environment Reference환경 레코드
에 함수 안의 함수와 변수를 기록
외부 렉시컬 환경 참조
에 function 오브젝트의 [[Scope]]를 설정
따라서 함수 안과 밖의 함수와 변수를 사용할 수 있게 됨
실행 콘텍스트(EC): {
렉시컬 환경 컴포넌트(LEC) = {
환경 레코드(ER): {
선언적 환경 레코드(DER): {
point: 123
},
오브젝트 환경 레코드(OER): {}
},
외부 렉시컬 환경 참조(OLEC): {}
},
변수 환경 컴포넌트(VEC): {},
this 바인딩 컴포넌트(TBC): {}
}
실행 콘텍스트(EC): {
글로벌 환경(GE): {
환경 레코드(ER): {
오브젝트 환경 레코드: 글로벌 오브젝트
},
외부 렉시컬 환경 참조(OLER): null
}
}
Global Environment
동적으로 함수와 변수 바인딩
외부 렉시컬 환경 참조 값은 null
스코프와 실행중인 함수가 Context 형태이므로
실행 콘텍스트에서
목적
악세스 메커니즘
obj의 프로퍼티가 변경되면 동적으로 참조
var obj = {point: 100};
obj.getPoint = function(){
return this.point;
};
obj.getPoint();
실행 콘텍스트(EC): {
렉시컬 환경 컴포넌트(LEC) = {
환경 레코드(ER): {
선언적 환경 레코드(DER): {},
오브젝트 환경 레코드(OER): {}
},
외부 렉시컬 환경 참조(OLEC): {}
},
변수 환경 컴포넌트(VEC): {},
this 바인딩 컴포넌트(TBC): {
point: 100,
getPoint: function(){}
}
}
getPoint() 함수에서 100이 반환되는 과정
준비 단계
마지막 줄에서 obj.getPont() 함수 호출
실행 콘텍스트 생성
3개의 컴포넌트 생성
this 바인딩 컴포넌트에
초기화 단계
실행 단계
return this.point; 실행
this 바인딩 컴포넌트에서 point 검색
this 바인딩 컴포넌트에
추가 설명
obj.getPoint()에서 obj의 프로퍼티가
var base = 200;
function getPoint(bonus){
var point = 100;
return point + base + bonus;
};
log(getPoint(70));
// 370
getPoint 오브젝트의 [[Scope]]에 글로벌 오브젝트 설정
마지막 줄에서 getPoint() 함수 호출하면
엔진은 실행 콘텍스를 생성하고 실행 콘텍스트 안으로 이동
준비 단계
컴포넌트를 생성하여 실행 콘텍스트에 첨부
환경 레코드를 생성하여 렉시컬 환경 컴포넌트에 첨부
<여기까지의 모습>
실행 콘텍스트(EC): {
렉시컬 환경 컴포넌트(LEC) = {
환경 레코드(ER): {}
},
변수 환경 컴포넌트(VEC): {},
this 바인딩 컴포넌트(TBC): {}
}
외부 렉시컬 환경 참조를 생성하여 렉시컬 환경 컴포넌트에 첨부하고
<여기까지의 모습>
실행 콘텍스트(EC): {
렉시컬 환경 컴포넌트(LEC) = {
환경 레코드(ER): {},
외부 렉시컬 환경 참조(OLEC): {
base: 200
}
},
변수 환경 컴포넌트(VEC): {},
this 바인딩 컴포넌트(TBC): {}
}
초기화 단계
호출한 함수의 파라미터 값을
함수 선언문을 function 오브젝트로 생성
함수 표현식과 변수에 초기값 설정
여기까지는 외부에 실행 상태를 제공하지 않음
<여기까지 모습>
실행 콘텍스트(EC): {
렉시컬 환경 컴포넌트(LEC) = {
환경 레코드(ER): {
bonus: 70,
point: undefined
},
외부 렉시컬 환경 참조(OLEC): {
base: 200
}
},
변수 환경 컴포넌트(VEC): {},
this 바인딩 컴포넌트(TBC): {}
}
실행 단계
함수 안의 코드를 실행
실행 콘텍스트 안에서 관련된 함수와 변수를 사용할 수 있음
call stack
First in Last Out 순서
가장 아래는 글로벌 오브젝트의 함수가 위치
function one(){
two();
log(1);
};
function two(){
three();
log(2);
};
function three(){
log(3);
};
one();
// 3
// 2
// 1
함수가 호출되면 3개의 파라미터 값을 실행 콘텍스트로 넘겨 줌
함수를 호출한 오브젝트를
함수 코드
호출한 함수의 파라미터 값
var obj = {};
obj.getTotal = function(one, two){
return one + two;
}
log(obj.getTotal(11, 22, 77));
// 33
실행 콘텍스트로 넘겨준 파라미터 값을 param이라고 하자
getTotal 오브젝트의 [[FormalParameters]]에서
name 배열을 하나씩 읽음
param에서 index번째의 값을 구함
name의 파라미터 이름과 4번에서 구한 값을
name을 전부 읽을 때까지 3번에서 5번까지 반복
var obj = {};
obj.getTotal = function(one, two){
var one;
log(one + two);
two = 77;
log("two:" + two);
}
obj.getTotal(11, 22);
// 33
// two:77
아래의 설명을 따라가면서 {key: value} 형태로 만들기
초기화 단계
obj.getTotal(11, 22) 함수가 호출되면
파라미터 이름에 값을 매핑하여
var one;
two = 77;
함수에 초기화할 코드가 없음
실행 단계
선언적 환경 레코드는 {one: 11, two: 22} 상태
var one;
console.log(one + two);
two = 77;
console.log("two:" + two);
var obj = {};
obj.getTotal = function(one, two, two){
log(one + two);
}
obj.getTotal(11, 22, 55);
// 66
위의 코드를 기준으로 엔진 관점에서 [실행 결과]에 출력된 값의 논리를 제시하세요.
힌트