코어 자바스크립트 : 02. 실행 컨텍스트 정리

yojuyoon·2020년 8월 26일
0

TIL👌

목록 보기
22/23
post-thumbnail

실행 컨텍스트란?

실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고, 이를 콜스택에 쌓아 올렸다가 가장 위에있는 컨텍스트와 관련 있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장한다.

  • 컨텍스트를 구성하는 방법으로는 전역공간, eval() 함수, 함수 실행 등이 있다.

스택과 큐

스택과 큐는 데이터 구조의 종류이다.

  • 스택은 출입구가 하나뿐인 깊은 우물같은 데이터 구조로, 데이터를 저장할 때와 반대되는 순서로 꺼내는 구조이다.
  • 큐는 양쪽이 열려있는 파이프와 같은 구조로, 단방향이라 한쪽은 입력만, 다른 한쪽은 출력만 담당하는 구조이다.

스택의 구조는 우물같은 구조라고 하였다. 때문에 이 구조를 잘 생각해보면 한 실행 컨텍스트가 콜 스택의 맨 위에 쌓이는 순간이 곧 현재 실행할 코드에 관여하게 되는 시점임을 알 수 있다. 기존 컨텍스트가 새로 쌓인 컨텍스트보다 아래에 위치할 수 밖에 없기 때문이다.

활성화된 실행 컨텍스트의 수집 정보는 다음과 같다.

VariableEnvironment

  • 현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보, 선언 시점의 LexicalEnvironment의 스냅샷. 변경사항 반영 X

VariableEnvironment는 LexicalEnvironment와 같지만 최초 실행 시 스냅샷을 유지한다는 점이 다르다. 실행 컨텍스트를 생성할 때 VariableEnvironment에 정보를 먼저 담은 다음 그대로 복사해서 LexicalEnvironment를 만들고 이후에는 LexicalEnvironment를 주로 활용하게 된다.

LexicalEnvironment

  • 처음에는 VariableEnvironment와 같지만 변경사항이 실시간으로 반영됨.

VariableEnvironment와 LexicalEnvironment 내부는 environmentRecord와 outer-EnvironmentReference로 구성되어 있다.

environmentRecod와 호이스팅

  • 현재 컨텍스트와 관련된 코드의 식별자 정보들이 순서대로 저장된다.

코드가 실행되기 전임에도 불구하고 자바스크립트 엔진은 이미 해당 환경에 속한 코드의 변수명을 모두 알고 있게 되는 셈.

자바스크립트 엔진은 식별자들을 최상단으로 끌어올려놓은 다음 실제 코드를 실행한다. 여기서 호이스팅 개념이 등장!

호이스팅 규칙

코드 해석을 좀 더 수월하게 하기 위해 environmentRecord의 수집 과정을 추상화한 개념으로, 실행 컨텍스트가 관여하는 코드 집단의 최상단으로 이들을 '끌어올린다'고 해석하는 것이다.

변수는 선언부와 할당부를 나누어 선언부를 끌어올리고, 함수 선언은 전체를 끌어올린다. 이 때 함수선언문함수 표현식으로 나뉜다.

함수 선언문과 함수 표현식

함수 선언문은 function 정의로 바로 함수를 선언하는 것이고 함수 표현식은 정의한 function을 별도의 변수에 할당하는 것을 말한다.

function a () { /*...*/ } // 함수 선언식

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

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

함수 선언문과 함수 표현식은 실무에서 발생할 수 있는 에러에서 디버깅 시에 큰 차이가 발생한다.

함수 선언식으로 함수를 작성하게 되면 전역 컨텍스트가 활성화 될 때 전역 공간에 선언된 함수들이 모두 가장 위로 끌어올려지고, 동일한 변수명에 서로 다른 값을 할당할 경우 나중에 할당한 값이 먼저 할당한 값을 덮어 씌우게 된다. 때문에 예를들어 5000줄의 코드가 있다고 가정하고 두 사람이 같은 파일에서 작업을 할 때 A, B 두 사람이 같은 파일 안에서 같은 이름의 함수를 함수선언식으로 만들 경우 실제로 호출되는 함수는 마지막에 선언된 함수 뿐이다.

스코프, 스코프 체인, outerEnvironmentReference

스코프(Scope)란 식별자에 대한 유효범위이다. 스코프 체인이란 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해나가는 것이다. 그리고 이를 가능하게 하는 것이 바로 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);

전역변수와 지역변수

전역 컨텍스트의 LexicalEnvironment에 담긴 변수를 전역변수이고, 함수 내부에서 선언한 변수는 무조건 지역변수이다. 안전한 코드 구성을 위해 가급적 전역변수의 사용은 최소화하는 것이 좋다.

읽어보면 좋을 글: [번역] 자바스크립트 스코프와 클로저(JavaScript Scope and Closures)

ThisBinding

this 식별자가 바라봐야 할 대상 객체.(챕터 3에서 자세히 다룸).

실행 컨텍스트를 활성화하는 당시에 지정된 this가 저장. 함수를 호출하는 방법에 따라 그 값이 달라지는데, 지정되지 않은 경우에는 전역 객체가 저장된다.

profile
하고싶은게 많은 사람. Front-end Developer

0개의 댓글