하루에 한 문제
실행 컨텍스트 본문
실행 컨텍스트란??
- 기존에 다른 언어를 사용해본 사람이라면 콜 스택(call stack)을 들어봤을 것이다.
- 이는 함수를 호출할 때 해당 함수의 호출 정보가 쌓여있는 스택을 의미한다.
- 실행 컨텍스트는 콜 스택에 들어가는 실행 정보 하나와 비슷하다.
- ECMAScript에서는 실행 컨텍스트를 "실행 가능한 코드를 형상화하고 구분하는 추상적인개념" 이라고 말한다.
- 이를 콜 스택과 연관해서 말해보자면 "실행 가능한 자바스크립트 코드 블록이 실행되는 환경" 이라고 할 수있고, 이 컨텍스트 안에 실행에 필요한 여러 가지 정보를 담고 있다.
- 위에서 말하는 실행가능한 코드 블록은 대부분의 경우 함수가 된다.
- ECMAScript에서는 실행 컨텍스트가 형성되는 경우를 세가지로 규정하고 있는데, 전역코드, eval()함수로 실행되는 코드, 함수 안의 코드를 실행할 경우이다.
- 대부분의 프로그래머는 함수로 실행 컨텍스트를 만든다.
- 코드 블록 안에 변수 및 객체, 실행가능한 코드가 들어있다. 이 코드가 실행되면 실행 컨텍스트가 생성되고 실행 컨텍스트는 스택안에 하나씩 차곡차곡 쌓이고, 가장 위에 위치하는 실행컨텍스트가 현재 실행되고 있는 컨텍스트이다.
- ECMAScript에서는 실행 컨텍스트의 생성을 "현재 실행되는 컨텍스트에서 이 컨텍스트와 관련 없는 실행 코드가 실행되면, 새로운 컨텍스트가 생성되어 스택에 들어가고 제어권은 그 컨텍스트로 이동한다" 라고 말한다.
console.log("This is global context");
function ExContext1() {
console.log("This is ExContext1");
};
function ExContext2() {
ExContext1();
console.log("This is ExContext2");
};
ExContext2();
위의 코드결과는 어떻게 나올까???
당연히 아래와 같이 나오게 된다.
실행 컨텍스트 생성 과정
아래의 코드를 보면서 실행 컨텍스트가 어떻게 생성되는 한번 보자
function excute(param1, param2) {
var a = 1, b = 2;
function func() {
return a + b;
}
return param1 + param2 + func();
}
excute(3, 4);
1. 활성 객체 생성
- 실행 컨텍스트가 생성되면 자바스크립트 엔진은 해당 컨텍스트에서 실행에 필요한 여러 가지 정보를 담을 객체를 생성한다.
- 이를 활성 객체라고 한다.
- 이 객체에 앞으로 사용할 매개변수나, 사용자가 정의한 변수 및 객체를 저장하고, 새로 만들어진 컨텍스트로 접근 가능하게 되어 있다.
- 이는 엔진 내부에서만 접근할 수 있고 사용자가 접근을 할 수는 없다.
2. arguments 객체 생성
- 다음 단계로는 argumetns 객체를 생성한다.
- 앞서 만들어진 활성 객체는 arguments 프로퍼티로 이 arguments 객체를 참조한다.
- 아래 그림은 execute() 함수의 param1과 param2가 들어왔을 경우 활성 객체의 상태를 표현한다!
3. 스코프 정보 생성
- 현재 컨텍스트의 유효 범위를 나타내는 스코프 정보를 생성한다.
- 이 스코프 정보는 현재 실행 중인 실행 컨텍스트 안에서 연결 리스트와 유사한 형식으로 만들어진다.
- 현재 컨텍스트에서 특정 변수에 접근해야 할 경우, 이 리스트를 활용한다
- 리스트는 현재 컨텍스트 변수 뿐 아니라, 상위 실행 컨텍스트의 변수도 접근이 가능하다.
- 만약 이 리스트에서 변수를 찾지 못하면 에러를 검출한다.
- 이 리스트를 스코프 체인이라고 하는데, [[scope]]프로퍼티로 참조한다.
4.변수 생성
- 현재 실행 컨텍스트 내부에서 사용되는 지역 변수의 생성이 이루어진다.
- ECMAScript 에서는 생성 되는 변수를 저장하는 변수 객체를 언급하는데, 실제적으로 앞서 생성된 활성 객체가 변수객체로 사용된다.(변수객체 = 활성객체)
- 변수 객체 안에서 호출된 함수 인자는 각각의 프로퍼티가 만들어지고 그 값이 할당된다.
- 만약 값이 넘겨지지 않았다면 undefined가 할당된다.
- execute()함수 안에 정의된 변수 a,b와 함수 func가 정의된다.
- 여기서 주의할 점은 이 과정에서는 변수나 내부 함수를 단지 메모리에 생성하고, 초기화는 각 변수나 함수에 해당하는 표현식이 실행되기 전까지는 이루어지지 않는다는 점이다.
- 따라서 변수 a와 b에는 먼저 undefined가 할당된다. (메모리만 생성)
- 표현식의 실행은 변수 객체의 생성이 다 이루어진 후 시작된다
5. this 바인딩
- 마지막 단계에서는 this키워드를 사용하는 값이 할당된다.
- this에 대한 내용은 앞에서 많이 설명했으니 모르면 블로그의 this글에서 보면 된다!
6.코드 실행
- 이렇게 하나의 실행 컨텍스트가 생성되고, 변수 객체가 만들어진 후에, 코드에 있는 여러가지 표현식 실행이 이루어진다.
- 이렇게 실행하면서 변수의 초기화 및 연산, 또다른 함수 실행등이 이루어진다.
- undefined가 할당된 변수 a와 b에도 이 과정에서 1,2값이 할당된다.
참고로 전역 실행 컨텍스트는 일반적인 실행 컨텍스트와는 다르다.
- argumetns 객체가 없으며, 전역 객체 하나만을 포함하는 스코프 체인이 있다.
- ECMAScript에서 언급된 바에 의하면 실행 컨텍스트가 형성되는 세 가지 중 하나로 전역코드가 있는데 이 전역 코드가 실행될 때 생성되는 컨텍스트가 전역 실행 컨텍스트다.
- 전역 실행 컨텍스트는 변수를 초기화하고 이것의 내부 함수는 일반적인 탑 레벨의 함수로 선언된다.
- 그리고 전역 실행 컨텍스트의 변수 객체가 전역 객체로 사용된다
- 즉, 전역 실행 컨텍스트에서는 변수 객체가 곧 전역 객체이다.
- 따라서 전역적으로 선언된 함수와 변수가 전역 객체의 프로퍼티가 된다.
- 전역 실행 컨텍스트 역시, this를 전역 객체의 참조로 사용한다.
참고
'Dev > JavaScript' 카테고리의 다른 글
클로저 (0) | 2021.04.15 |
---|---|
스코프 체인 (2) | 2021.04.14 |
프로토타입 체이닝 (0) | 2021.04.13 |
함수 리턴 (0) | 2021.04.09 |
함수 호출과 this (0) | 2021.04.09 |
Comments