티스토리 뷰

실행 컨텍스트

  • 자바 스크립트가 실행 될 때 생성되는 하나의 실행 단위입니다.

  • 자바 스크립트는 자신만의 독특한 과정으로 신행 컨텍스트를 만들고 그 안에서 실행이 이루어 집니다.

  • 이 실행 컨텍스트는 자신만의 유효 범위(Scope - 스코프)를 갖는데 이 과정에서 클로저를 구현할 수 있습니다.

  • 실행할 코드에 제공할 환경 정보들을 모아놓은 객체입니다.

 

실행 컨텍스트의 개념

실행 컨텍스트를 이해하려면 콜 스택(call stack)이라는 개념이 필요합니다.

콜스택은 함수를 호출할 때 해당 함수의 호출 정보가 차곡차곡 쌓여있는 스택을 말합니다.

예를 들어서 빠저 나올수 없는 통로에 짐을 하나씩 넣습니다.

그렇게 되면 가장 나중에 들어간 짐이 가장빨리 나오게 되고 제일 먼저 들어간 짐이 가장 나중에 나오게 됩니다.

이미지 출처 :  programiz.com

위 그림처럼 요소를 넣으면 차곡 차곡 쌓이게 됩니다.

하지만 삭제를 하게 되면 가장 나중에 들어온 것이 가장 먼저 나가게 됩니다.

이것을 LIFO(Last - In - First - Out)이라고 합니다.

자바 스크립트는 동일한 환경에 있는 환경 정보들을  모은 실행 컨텍스트를

콜스택에 쌓아올린 후 실행하여 코드의 환경과 순서를 보장할 수 있게 됩니다.

즉, 스택의 경우 FILO(First In, Last Out)의 구조이기에 순서를 보장하고,

콜스택 내부에 쌓인 실행 컨텍스트의 정보를 통해 환경을 보장할 수 있는 것입니다.

실행 컨텍스트가 형성되는 세가지 경우

1. 전역공간
2. eval()함수
3. 함수(우리가 흔히 실행컨텍스트를 구성하는 방법)

 

대부분의 프로그래머는 함수로 실행 컨텍스트를 만들고 이 코드 블록 안에는 변수 및 객체, 실행 가능한 코드가 들어있습니다.

이 코드가 실행되면 실행컨텍스트가 생성되고, 실행 컨텍스트는 스택 안에 하나씩 차곡 차곡 쌓이고,

제일 위top에 위치하는 실행 컨텍스트가 현재 실행되고 있는 컨텍스트가 됩니다.

console.log('this is global');

function func1(){
    console.log('this is func1');
}

function func2(){
    func1();
    console.log('this is func2');
}
func2();
// this is global
// this is func1
// this is func2

위 코드의 결과를 보면 전역 실행 컨텍스트가 가장 먼저 실행되고 새로운 함수 호출이 발생하면 새로운 컨텍스트가 만들어지고 실행되며, 종료되고 반환됩니다. 

코드실행 → 전역(in) → 전역(중단) + func2(in) → func2(중단) + func1(in) → func1(out) +   func2 (재개)
→ func2 (out) + 전역(재개) → 전역(out) → 코드종료

 

실행 컨텍스트 객체의 정보

1. VariableEnvironment

    • 현재 컨텍스트 내부의 식별자 정보(environmentRecord)를 가지고 있습니다.

       → var a = 3일때 var a를 의미합니다.

    • 외부 환경 정보(outerEnvireonmentReference)를 가지고 있습니다.

    → VariableEnvironment에 먼저 정보를 담고 그대로 LexicalEnvironment에 snapshot합니다. 

 

    * environmentRecord 

      ■ 현재 컨텍스트와 관련된 식별자와 식별자에 바인딩 된 값이 기록되는 공간입니다. 

          (함수에 지정된 매개변수 식별자, 함수자체, var로 선언된 변수 식별자)

 

    * snapshot : 특정 시점에서의 상태나 정보의 사본

    * 프로그래밍컨텍스트의 snapshot : 어떤 데이터나 상태의 현재 상태를 저장하고

                                                                         나중에 참조하거나 복원할 수 있도록 하는것

2. LexicalEnvironment

    • LexicalEnvironment는 초기에는 VariableEnvironment와 같지만 변경사항을 실시간으로 반영합니다.

    • VariableEnvironment의 초기 상태를 기억하고 있으며 LexicalEnvironment의 최신 상태를 저장합니다.

    environmentRecord 

      ■ 현재 컨텍스트와 관련된 식별자와 식별자에 바인딩 된 값이 기록되는 공간입니다. 

      ■ 실행 컨텍스트 내부 전체를 처음부터 끝까지 확인하며 순서대로 수집합니다.

          (함수에 지정된 매개변수 식별자, 함수자체, var로 선언된 변수 식별자)

    변수 정보 수집을 모두 마쳤지만 실행 컨텍스트가 관여할 코드는 실행 전의 상태입니다.

    js엔진은 코드 실행 전 이미 모든 변수정보를 알고 있습니다.

 

2 - 1 호이스팅(Hoisting)[ LexicalEnvironment - environmentRecord  ]

자바스크립트 엔진이 실행 컨텍스트를 구성할 때 environmentRecord에 식별자의 정보를 수집합니다.

이러한 과정을 통해 엔진은 함수를 실행하기도 전에 해당 컨텍스트 내부의 변수명들을 이미 알고 있습니다.

이 때 식별자들을 코드의 최상단으로 끌어올렸다 라는 호이스팅 개념이 생겨 났습니다.

즉, 함수의 정의를 해당 범위의 선두로 끌어올려 처리하는 것으로 전역 개념으로 설정되는 것을 의미 합니다.

 

•  호이스팅 규칙 1 : 매개 변수 및 변수는 선언부를 호이스팅 합니다.

function a () {
	var x = 1;
	console.log(x); // 1
	var x;
	console.log(x); // 1
	var x = 2;
	console.log(x); // 2
}
a(1);

var x가 위로 올라가 밑에는 초기화만 한 형태로 바뀌면서 값이 들어가게 됩니다.

 

•  호이스팅 규칙 2 : 함수 선언은 전체를 호이스팅합니다. but 함수 표현식은 변수 부분만 호이스팅됩니다.

function a () {
	console.log(b); // [Function: b]
	var b = 'bbb';
	console.log(b); // bbb
	function b() { }
	console.log(b); // bbb
}
a();

함수는 호이스팅 되어 var b와 같이 함수의 상단에 위치파게 되어 아무 선언 되지 않은 b가 함수 b가 되었습니다.

console.log(sum(1, 2)); // 3 
console.log(multiply(3, 4)); // multiply is not a function at Object.

function sum (a, b) { // 함수 선언문 sum
	return a + b;
}

var multiply = function (a, b) { // 함수 표현식 multiply
	return a + b;
}

함수 선언문은 전체 호이스팅되어 값이 잘나오는걸 볼수 있지만  함수 표현식은 변수 선언부만 호이스팅되어 에러가 난걸 볼수 있습니다.

 

함수 호이스팅 정리

console.log(func1('대한','민국'));
console.log(func2(1,10)); // 함수 표현식은 호이스팅 되지 않아 호출 불가.

console.log(func2);// undefined
// func2에 대한 var선언으로 변수 자체는 호이스팅되지만
// 아래 정의한 함수 표현식은 호이스팅되지 않아
// undefined반환.

function func1(string1,string2){
    return string1 + string2;
}
//함수의 선언은 함수 호출 호이스팅으로 인한 함수 선언위치레 관계 없이
//어디서든 호출가능.

var func2 = function(st, ed){
    let tot = 0;
    for(let i = st; i<=ed; i++){
        tot += i;
    }
    return tot;
}
//함수 표현식은 호이스팅되지 않지만 var구문 변수의 선언은
//호이스팅되는 것을 확인 가능.

console.log(func2);
console.log(func2(1,100));

 

 

2 - 2 스코프(scope), 스코프 체인(Hoisting)[ LexicalEnvironment - outerEnvireonmentReference ]

outerEnvireonmentReference 

스코프 체인이 가능토록 하는것(외부 환경의 참조정보)입니다.

 

스코프

식별자에 대한 유효 범위를 말합니다.

• 대부분의 언어에서 존재하며 자바스크립트에서도 존재합니다.

2가지 스코프 타입이 존재 합니다. global(전역)과  local(지역)

   ■ 전역스코프(Global Scope) - 전역에 선언되어 있어 어느 곳에서든지 해당  변수에 접근을 할 수 있습니다. 

   ■ 지역스코프(Local Scope) - 해당 지역에서만 접근할 수 있어 지역을 벗어난 곳에선 접근을 할 수 없습니다.

   자바스크립트에서 함수를 선언하면 함수를 선언할 때 마다 새로운 스코프를 생성하게 됩니다.

   함수 몸체에 선언한 변수는 해당 함수 안에서만 접근을 할수가 있는데 이를 함수 스코프(function - scoped)라고 합니다.

 

스코프 체인

식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해 나가는 것입니다.

outer는 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조 합니다. 

outer는 자신이 선언된 시점의 LexicalEnvironment를 참조하므로 가장 가까운 요소부터 차례대로 접근이 가능하게 됩니다.

var a = 1;
var outer = function() {
	var inner = function() {
		console.log(a); 
		var a = 3;
	};
	inner();
	console.log(a); 
};
outer(); // undefined 1
console.log(a); // 1

inner함수는 var이 호이스팅되어 undefined가 됩니다.

outer함수를 호출하게 되면 outer함수 내부에는 a가 정의 되어 있지 않기 때문에 scope chain을 통해 전역에 초기화 되어있는 a로 값을 초기화 하여 출력됩니다.

 

 

즉, 각각의 실행 컨텍스트는 LexicalEnvironment안에 record와 outer를 가지고 있고, outer안에 그 실행 컨텍스트가 선언될 당시의 LexicalEnvironment정보가 다 들어 있으므로 scope chain에 의해 상위 컨텍스트의 record를 읽어 올수 있습니다.

 

3. this binding

이 부분은 여기를 참고해 주세요!

 

JavaScript에서의 this란?

Java에서의 this, Python에서의 self는 명확하게 현재 인스턴스 자신을 나타냅니다. 객체 내에서 this를 씀으로써 자신의 인스턴스 변수나 함수에 접근을 할수가 있습니다. 하지만 JavaScript에서의 this는

startcoriny.tistory.com

 

 

 

 

배워나가는 코린이 입니다!!

부족한게 있다면 댓글로 지적해주세요!! 감사합니다!😊

'프로그래밍 기초 > JavaScript' 카테고리의 다른 글

Promise / 비동기 작업의 동기적 표현  (0) 2024.01.10
TIL 9일차 + 콜백 함수란?  (2) 2024.01.04
TIL 7일차 + 배열이란?  (2) 2024.01.02
JavaScript에서의 this란?  (0) 2024.01.02
구조 분해 할당이란?  (1) 2024.01.02
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함