코어자바스크립트

[CoreJavaScript] Chapter 02. 실행 컨텍스트 내용 정리

Hyunsangs 2024. 9. 13. 16:16

2-1 실행 컨텍스트란 ?


실행 컨텍스트 : 실행할 코드에 제공할 환경 정보들을 모아놓은 객체

→ 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성.

→ 콜 스택에 쌓아올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련 있는 코드들을 실행하는 식

( 전체 코드의 환경과 순서를 보장)

스택 : 출입구가 하나뿐인 깊은 우물 같은 데이터 구조

→ a,b,c,d를 저장했다면 d,c,b,a 순으로 꺼낼 수 밖에 없다. (LIFO)

큐 : 양쪽이 모두 열려있는 파이프 구조

→ 종류에 따라 양쪽 모두 입력과 출력이 가능하나, 한쪽은 입력만 다른 한쪽은 출력을 담당.

→ a,b,c,d,를 저장했다면 a,b,c,d 순으로 꺼낸다.(FIFO)

 

2-1 실행 컨텍스트와 콜 스텍

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

outer();
console.log(a); // 1

전역 컨텍스트는 자바스크립트 코드를 실행하는 순간 전역 컨텍스트가 콜 스택에 담긴다. 파일이 열리는 순간 전역 컨텍스트가 활성화 된다고 보면 된다.

** 전역 컨텍스트 개념 = 실행 컨텍스트 개념

어떤 실행 컨텍스트가 활성화될 때 자바스크립트 엔진은 해당 컨텍스트에 관련된 코드들을 실행하는 데 필요한 환경 정보들을 수집해서 실행 컨텍스트 객체에 저장

** 이 객체는 자바스크립트 엔진이 활용할 목적으로 생성할 뿐 개발자가 코드를 통해 확인 불가

  • 활성화 된 실행 컨텍스트 수집 정보
    • VariableEnvironment : 현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보, 선언 시점의 LexicalEnvironment의 스냅샷으로, 변경 사항은 반영 x
    • LexicalEnvironment: 처음에는 VariableEnvironment와 같지만 변경 사항이 실시간 반영.
    • ThisBinding : This 식별자가 바라봐야 할 대상 객체.

2-2 VariableEnvironment


VariableEnvironment 내용 = LexicalEnvironment 내용 이지만, 최초 실행 시의 스냅샷을 유지하는 점이 다름.

실행 컨텍스트 생성 시, VariableEnvironment 정보 담음

→ 이를 그대로 보사해서 LexicalEnvironment 만듬.

→ 이후 LexicalEnvironment주로 활용.

2-3 LexicalEnvironment


2-3-1 environmentRecord와 호이스팅

environmentRecord : 현재 컨텍스트와 관련된 코드의 식별자 정보들을 저장.

  • 컨텍스트 내부 전체를 처음부터 끝까지 순서대로 수집

자바스크립트 엔진은 식별자들을 최상단으로 끌어올려놓은 다음 실제 코드를 실행한다.

호이스팅 : ‘끌어올리다’ 의미로 변수 정보를 수집하는 과정을 더욱 이해하기 쉬운 방법으로 대체한 가상의 개념

  • 자바스크립트 엔진이 실제로 끌어올리지는 않지만 편의상 끌어올린것으로 간주.

호이스팅 규칙

매개변수와 변수에 대한 호이스팅(1) - 원본코드

function a (x) {
	console.log(x); // (1) 예상 : 1
	var x;
	console.log(x); // (2) 예상 : undefined
	var x = 2;
	console.log(x); // (3) 예상 : 2
}
a(1);

매개변수와 변수에 대한 호이스팅(2) - 매개변수를 변수 선언/할당과 같다고 간주해서 변환한 상태

function a () {
	var x = 1;  // 매개변수 선언
	console.log(x); // (1)
	var x;
	console.log(x); // (2)
	var x = 2;
	console.log(x); // (3)
}

변수 정보를 수집하는 과정 즉 호이스팅 처리 시

매개변수와 변수에 대한 호이스팅(3) - 호이스팅을 마친 상태

function a () {
	var x; // 변수 x 선언 → 메모리에서 저장 공간 확보, 주솟값을 변수 x에 연결
	var x; // 다시 변수 x 선언 
	var x; // 무시

	x = 1; // x에 1을 할당 → 1을 별도의 메모리에 담고, 주솟값 입력
	console.log(x); // 1
	console.log(x); // 1
	x = 2; // x에 2를 할당 → 2을 별도의 메모리에 담고, 1을 가리키는 주솟값을 2를 가리키는 주소값으로 대치
	console.log(x); // 2
}

a(1);

→ environmentRecord는 변수명만 끌어 올리고 할당 과정은 원래 자리에 그대로 남겨둔다.

→ 매겨변수의 경우도 마찬가지. environmentRecord의 관심사에 맞춰 수집 대상 1,2,3을 순서대로 끌어올린다.

→ 함수 선언식도 호이스팅이 된다.

함수 선언문과 함수 표현식

함수 선언문 : function 정의부만 존재하고 별도의 할당 명령이 없는 것을 의미

  • 반드시 함수명의 정의 되어야 함.

함수 표현식 : 정의한 function을 별도의 변수에 할당하는 것을 의미.

  • 함수명의 정의 되지 않아도 됨. (정의 하지 않으면 - 익명 함수 표현식 / 정의 하면 - 기명 함수 표현식)

함수를 정의하는 세 가지 방식

function a () {} // 함수 선언문
a(); // 실행 o

var b = function () {} // (익명) 함수 표현식
b(); // // 실행 o

var c = function d () {} // 기명 함수 표현식
c(); // 실행 o
d(); // error (함수명은 오직 내부에서만 접근 가능)

함수 선언문과 함수 표현식(1) - 원본코드

console.log(sum(1,2));
console.log(multiply(3,4));

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

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

함수 선언문과 함수 표현식 (2) - 호이스팅 마친 상태

var sum = function sum (a,b) { // 함수 선언문은 전체를 호이스팅
	return a + b;
}
var multiply; // 변수 선언부만 끌어올림.

console.log(sum(1,2));
console.log(multiply(3,4));

multiply = function (a,b) { // 변수의 할당부는 원래 자리에 남겨짐.
	return a * b;
}

호이스팅이 된 결과

console.log(sum(1,2)) 은 → 3으로 정상 작동

console.log(multiply(3,4)) 은 → 비어있는 대상을 함수로 여기기 때문에 ‘multiply is not a function’ 이라는 에러 메세지를 출력.

함수 선언문은 → 전체를 호이스팅을 진행

함수 표현식은 → 변수 선언부는 끌어 올리고 할당한 부분은 원래 자리에 남는 차이가 있다.

2-3-2 스코프, 스코프 체인, outerEnvironmentReference

스코프 : 식발자에 대한 유효 범위

  • 오직 함수에 의해서만 스코프가 생성.

스코프 체인: 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해나가는 것

  • 이것을 가능케 하는 것이 바로 LexicalEnvironment의 두 번째 수집 자료인 outerEnvironmentReference

outerEnvironmentReference : 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조.

→ 선언하는 행위 : 콜 스택 상에서 어떤 실행 컨텍스트가 활성화된 상태일 때뿐!!!

스코프 체인

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

L.E : LexicalEnvironment / e : enivronmentRedcord / o : outerEnvironmentReference

전체 윤곽

전역 컨텍스트 → outer컨텍스트 → inner 컨텍스트 순으로 점차 규모가 작아지는 반면 스코프 체인을 타고 접근 가능한 변수의 수는 늘어남.

변수 은닉화 : inner 함수 내부에서 a 변수를 선언했기 때문에 전역 공간에서 선언한 동일한 이름의 a 변수에는 접근할 수 없음

2-4 this


실행 컨텍스트의 thisBinding에는 this로 지정된 객체가 저장

실행 컨텍스트 활성화 당시에 this가 지정 되지 않은 경우 this는 전역 객체가 저장.

그밖에 함수를 호출하는 방법에 따라 this에 저장 되는 대상이 달라짐.