210110 TIL 실행컨텍스트

ToastEggsToast·2021년 1월 10일
0

TIL

목록 보기
8/15

본문은 코어자바스크립트를 기반으로 작성되었습니다.

📚 실행컨텍스트

📖 실행컨텍스트란?

실행할 코드에 제공할 환경 정보들을 모아놓은 객체로, 자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념.

자바스크립트는 어떤 실행 컨텍스트가 활성화되는 시점에 선언된 변수를 위로 끌어올리고(호이스팅), 외부 환경 정보를 구성하고, this값을 설정하는 등의 동작을 수행합니다. 자바스크립트 엔진이 활용할 목적으로 생성할 뿐 개발자가 코드를 통해 직접 확인할 수는 없습니다.

📖 스택 - 큐

스택(stack)

출입구가 하나뿐인 깊은 우물 같은 데이터 구조입니다.
main > avaerage > add 순서대로 스택이 쌓이면, add > average > main 순으로 실행 됩니다.

큐(queue)

양쪽이 모두 열려있는 파이프와 같은 데이터 구조입니다.
1 > 2 > 3 > 4 > 5 > 6 > 7 순서로 데이터가 입력되고(enqueue), 입력된 순서와 똑같이 1 > 2 > 3 > 4 > 5 > 6 > 7 순서로 데이터가 출력(dequeue)됩니다.

콜스택(call stack)

동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고, 이를 콜 스택에 쌓아올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련 있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장합니다. 자동으로 생성되는 전역공간과 eval()을 제외하면 '함수를 실행하는 것'이 우리가 흔히 실행 컨텍스트를 구성할 수 있는 방법이 됩니다.

콜스택 예제

// ------- (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

📖 VariableEnvironment, LexicalEnvironment, ThisBinding

실행 컨텍스트에 담기는 정보들로, 위에서 언급한 것 처럼 개발자가 직접 코드를 작성해 확인할 수 없습니다.

📝 VariableEnvironment

현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보. 선언 시점의 LexicalEnvironment의 스냅샷(snapshot)으로, 변경 사항은 반영되지 않는다.

실행 컨텍스트를 생성할 때 VariableEnvironment에 정보를 먼저 담은 다음, 이를 그대로 복사해서 LexicalEnvironment를 만들고, 이후에는 LexicalEnvironment를 주로 활용하게 됩니다.
VariableEnvironment와 LexicalEnvironment의 내부는 environmentRecord와 outerEnvironmentReference로 구성되어 있습니다. 초기화 과정 중에는 사실상 완전히 동일하고 이후 코드 진행에 따라 서로 달라집니다.

📝 LexicalEnvironment

컨텍스트를 구성하는 환경 정보들을 사전에서 접하는 느낌으로 정보를 담아놓았습니다.

EnvironmentRecord와 호이스팅(Hoisting)

environmentRecord에는 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장됩니다. 매개변수 식별자, 함수 자체, var로 선언된 변수의 식별자 등이 식별자에 해당합니다. 컨텍스트 내부 전체를 처음부터 끝까지 쭉 훑어나가며 "순서대로" 수집합니다.

코드가 실행되기 전임에도 불구하고 자바스크립트 엔진은 이미 해당 환경에 속한 코드의 변수명들을 모두 알고있게 되는 셈입니다. 이러한 개념을 호이스팅이라고 합니다. 호이스팅은 과정을 쉽게 이해하기 위한 "가상의 개념"입니다.

함수 선언문과 함수 표현식

  • 함수 선언문: function 정의부만 존재하고 별도의 할당 명령이 없는 것.
  • 함수 표현식: 정의한 function을 별도의 변수에 할당하는 것.
  • 함수명을 정의한 함수 표현식을 '기명 함수 표현식', 정의하지 않은 것을 '익명 함수 표현식'이라고 부르기도 합니다.
function a () {   } // 함수 선언문. 함수명 a 가 곧 변수명.
a(); // 실행 가능.

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

var c = function d () {   } // 기명 함수 표현식. 변수명은 c, 함수명은 d.
c(); // 실행 가능.
d(); // 실행 불가능. 재귀함수 등과 같이 함수 내부에서 호출할 경우에는 사용 가능함.

스코프(scope)

스코프란 식별자에 대한 유효범위입니다. ES5까지의 자바스크립트는 특이하게도 전역 공간을 제외하면 오직 함수에 의해서만 스코프가 생성됩니다.

스코프 체인(scope chain)

식별자의 범위인 '스코프'를 안에서부터 바깥으로 차례로 검색해나가는 것을 의미합니다. 이를 가능케 하는것이 바로 LexicalEnvironment의 두 번째 수집 자료인 outerEnvironmentReference 입니다.

outerEnvironmentReference

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

변수 은닉화(variable shadowing)

스코프 체인 상에 있는 변수라고 해서 무조건 접근 가능한 것은 아닙니다. 함수 내부에서 a라는 변수를 선언했고, 전역 공간에도 같은 a라는 이름을 가진 변수가 존재 할 경우, 전역 공간에서 선언한 동일한 이름의 a변수에는 접근할 수 없게 됩니다(함수 내부에서부터 먼저 탐색하기 때문에). 이를 변수 은닉화라고 합니다.

전역변수와 지역변수

  • 전역변수: 전역 스코프에서 선언한 변수
  • 지역변수: 함수 내부에서 선언한 변수
  • 코드의 안전성을 위해 가급적 전역 변수 사용을 최소화하고자 노력하는 것이 좋음.

📖 this

실행 컨텍스트의 thisBinding에는 this로 지정된 객체가 저장됩니다. 실행 컨텍스트 활성화 당시에 this가 지정되지 않은 경우 > this에는 전역 객체가 저장됩니다. 그 밖에는 함수를 호출하는 방법에 따라 this에 저장되는 대상이 달라집니다.

profile
개발하는 반숙계란 / 하고싶은 공부를 합니다. 목적은 흥미입니다.

0개의 댓글