Skip to content

Latest commit

 

History

History
230 lines (155 loc) · 8.97 KB

실행 컨텍스트.md

File metadata and controls

230 lines (155 loc) · 8.97 KB

실행 컨텍스트

실행 컨텍스트 : 실행할 코드에 제공할 환경 정보들을 모아 놓은 객체 혹은 함수를 실행할 때 필요한 환경정보를 담은 객체

  • 자바스크립트는 어떤 실행 컨텍스트가 활성화되는 시점에 선언된 변수를 위로 끌어올리고(호이스팅), 외부 환경 정보를 구성하고, this 값을 설정하는 등의 동작을 수행함
  • 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고, 이를 **콜 스택(=호출 스택)**에 쌓아올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련 있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서 보장함
  • 우리가 흔히 실행 컨텍스트를 구성하는 방법은 함수를 실행하는 것임

1) 스택(stack)과 큐(queue)

스택(stack) : 출입구가 하나뿐인 깊은 우물 같은 데이터 구조 혹은 현재 어떤 함수가 동작 중인지 다음에 어떤 함수가 호출될 예정인지 등을 제어하는 자료구조임

  • 용량보다 많은 데이터를 저장하려고 하면 넘친다 → stack overflow

큐 (queue) : 양쪽이 모두 열려 있는 파이프 같은 데이터 구조

RubberDuck

  • 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고, 이를 콜 스택(call stack)에 쌓아 올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련 있는 코드들을 실행하는 방식으로 전체 코드의 환경과 순서를 보장!

실행 컨텍스트와 콜 스택 예시)

// ------------------------------ (1)
var a = 1;
function outer() {

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

 결과 : 
undefined
1
1

RubberDuck

실행 컨텍스트 내부

RubberDuck

VariableEnvironment :

  • 현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보임
  • 식별자 정보 수집함, 변화가 실시간 반영 X
    • 선언시점의 스냅샷으로 변경사항은 반영되지 않음

LexicalEnvironment :

  • 처음에는 VariableEnvironment와 같지만, 변경사항이 실시간으로 반영됨.
  • 각 식별자의 ‘데이터’ 추적함, 변화가 실시간 반영 O
💡 위 둘의 차이점은 변화가 실시간으로 반영되는지 안되는지의 차이가 있다.

ThisBinding : this 식별자가 바라봐야 할 대상 객체.

참고) 식별자 : 어떤 데이터를 식별하는데 사용하는 이름 (=변수명)

VariableEnvironment

  • VariableEnvironment 에 담기는 내용은 LexicalEnvironment와 같지만, 최초 실행 시의 스냅샷을 유지한다는 점이 다르다.
  • 실행 컨텍스트를 처음 생성할 때 VariableEnvironment에 정보를 먼저 담고, 이를 그대로 복사해서 LexicalEnvironment를 만들고, 이후에는 LexicalEnvironment를 주로 활용한다.
  • VariableEnvironmentLexicalEnvironment 내부는 environmentRecord와 outer-EnvironmentReference로 구성함

LexicalEnvironment

  • 일반적으로 ‘어휘적/사전적 환경’ 이라고 함
  • 수시로 변하는 환경 정보임

2) environmentRecord와 호이스팅

environmentRecord

  • environmentRecord에는 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장됨 (매개변수의 이름, 함수 선언, 변수명 등)
  • 컨텍스트 내부 전체를 처음부터 끝까지 쭉 훑어나가며 순서대로 수집함

호이스팅

  • 호이스팅(hoisting) : 변수 정보를 수집하는 과정을 더욱 이해하기 쉬운 방법으로 대체한 가상의 개념임
    • 즉, 식별자 정보를 (실행 컨텍스트) 끌어올린 것

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

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

a(1)
  • 위 예제에서 (1)은 함수 호출 시 전달한 1, (2)는 할당값이 없는 undefine, (3)에는 할당된 2가 나올 거라고 예측했는데 전혀 다른 결과가 나왔다.

RubberDuck

왜 그러한 결과가?

기존코드에서 호이스팅을 마친 상태)

function a (x) {
	var x;  // 수집 대상 1의 변수 선언 부분
	var x;  // 수집 대상 2의 변수 선언 부분
	var x;  // 수집 대상 3의 변수 선언 부분

	x = 1;  // 수집 대상 1의 할당 부분
	console.log(x); //------------ (1)
	console.log(x); //------------ (2)
	x = 2; // 수집 대상 2의 할당 부분
	console.log(x); //------------ (3)
}

a(1)
  • 변수를 호이스팅할 때 변수 선언부만 끌어올리고 할당부는 원래 자리에 그대로 둔다.
  • 함수 선언(문)을 호이스팅할 때 함수 전체를 끌어올림

호이스팅 다른 예시)

RubberDuck
RubberDuck

  • 함수 선언문은 전체가 끌어 올려진다.

3) 함수 선언문과 함수 표현식

  • 함수 선언문 : function 정의부만 존재하고, 별도의 할당 명령이 없음
    • 반드시 함수명이 정의돼 있어야 함
  • 함수 표현식 : 정의한 function을 별도의 변수에 할당하는 것
    • 기명 함수 표현식 : 함수명을 정의한 함수 표현식
    • 익명 함수 표현식 : 함수명을 정의하지 않은 표현식
function a () {} // 함수 선언문. 함수 a가 곧 변수명
a(); // OK

var b = function () {} // (익명) 함수 표현식. 변수명 b가 곧 함수명.
b();  // OK

var c = function d() {} // 기명 함수 표현식. 변수명은 c, 함수명은 d.
c(); // OK
d();  // ERROR

호이스팅 시 차이점

  • 함수 선언문 : 전체를 호이스팅함
  • 함수 표현식 : 변수는 선언부만 끌어올림 (할당부 이후부터 실행 가능)

스코프, 스코프 체인, outerEnvironmentReference

  • 스코프(scope) : 변수(식별자)에 대한 유효범위
    • 즉, 변수의 유효범위
  • 스코프 체인: ‘변수의 유효범위'를 안에서부터 바깥으로 차례로 검색해나가는 것
    • 스코프 체인은 외부로 나갈 수 있는데 자기 기준에서 안으로 들어갈 수 X

스코프 체인 예시)

RubberDuck

  • 위는 inner 내부에서 전역 컨텍스트 까지 가장 가까운 자기 자신부터 멀리 있는 스코프를 찾아가는 것이다.

참고) 식별자 : 어떤 데이터를 식별하는데 사용하는 이름 (=변수명)

outerEnviron mentReference

  • “외부 환경에 대한 참조”라는 의미임
    • 환경은 Lexical Environment를 의미함
  • 스코프 체인을 가능케 하는 것이 outerEnvironmentReference이다.
  • outerEnvironmentReference는 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조한다.

스코프 체인

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

outer();
console.log(a)

// 결과:
undefined
1
1

전역변수와 지역변수

  • 전역 공간에서 선언한 변수는 ‘전역변수’이고,
  • 함수 내부에서 선언한 변수는 ‘지역변수’이다.
    • 위 스코프 체인 예시에서 전역 변수는 전역 스코프에서 선언한 a와 outer이다.
    • 지역 변수는 outer 함수 내부에 선언한 inner과, inner함수 내부에 선언한 a이다
  • 코드의 안전성을 위해 가급적 전역변수 사용을 최소화하고, 지역 변수를 사용하는 것이 좋다.

참고

  • 정재남, 코어 자바스크립트