내일 또 면접인데 준비하다가 테코톡의 실행 컨텍스트 정리 영상을 보고 너무 좋아 정리해보고자 한다.
https://www.youtube.com/watch?v=EWfujNzSUmw&t=32s 하루의 실행 컨텍스트 링크
실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
여기서 환경이란, 코드 실행에 영향을 주는 조건이나 상태를 뜻한다.
자바스크립트는 동일한 환경에 있는 환경 정보들을 모은 실행 컨텍스트를 콜스택에 쌓아올린 후 실행하여 코드의 환경과 순서를 보장할 수 있게 된다.
풀어서 설명하면 스택의 경우 FILO (First In, Last Out) 의 구조이기에 순서를 보장, 콜스택 내부에 쌓인 실행 컨텍스트의 정보를 통해 환경을 보장할 수 있는 것이라 생각한다.
여기서 환경이란 전역공간이 될 수 있고, 함수 즉 함수 내부의 환경이 될 수도 있다.
기본적으로 실행 컨텍스트는 Record, Outer로 이루어져 있다.
만약 자바스크립트를 실행시키면, 자바스크립트 엔진은 콜스택에 전역 실행 컨텍스트를 담는다.
그 후, A라는 함수를 실행시키면 A의 실행 컨텍스트를 담는다.
콜 스택에서는 가장 위에 있는 실행 컨텍스트만 활성화되므로, 현재 활성화된 실행 컨텍스트는 A의 실행 컨텍스트이다.
console.log(a); // undefined
var a = 'messi';
console.log(a) // messi
호이스팅은 선언문이 최상단으로 끌어올려진 것 같은 현상으로, 이는 자바스크립트 엔진이 먼저 전체 코드를 스캔하면서 변수나 함수 같은 정보를 실행 컨텍스트의 Record에 기록해놓기 때문이다.
ECMAScript에 나오는 정식 명칭은 환경 레코드로, 식별자와 식별자에 기록된 값을 저장해놓는 객체이다.
자바스크립트 엔진은 코드를 실행하면 콜스택에 전역 컨텍스트 하나를 채워넣는다. 그 후, 전체 코드를 스캔하면서 선언할 게 있는지 찾아보고, 있다면 먼저 선언해둔다.
환경 레코드에 식별자를 등록해놓는 것이다.
var로 변수를 설정할 경우 선언과 동시에 undefined로 값을 바인딩한다.
let, const로 변수를 설정할 경우, 선언만 실행하고 값을 바인딩하는 과정은 거치지 않는다.
즉 let, const로 설정하면 선언 라인 이전에 식별자를 참조할 수 없는데, 이 구역을 일시적 사각지대라고 한다.
함수도 비슷한데, 화살표 함수를 var로 설정할 경우 선언 라인 이전에 함수를 참조하려 하면 undefined를 확인할 수 있고, let, const로 설정하면 환경 레코드에 등록된 값이 없어 typeError를 확인할 수 있다.
위와 같이 변수에 함수를 담아 선언하는 형태를 함수 표현식이라고 하는데, 함수 표현식을 이용할 경우 변수 호이스팅 효과를 그대로 받을 수 있다.
반면 함수 선언문, 그러니까 function 키워드를 이용한 함수는 선언과 동시에 함수가 생성되어, 선언 전에도 함수를 이용할 수 있다(TDZ가 없다).
이번엔 Outer인데, 본명은 Outer Environment Reference로, 외부 환경 참조라는 이름으로 불린다. 이는 바깥 Lexical Environment를 가리킨다.
실행 컨텍스트의 Outer, Record를 합쳐서 Lexical Environment라고 한다.
Outer는 간단히 말해서 해당 컨텍스트의 상위 스코프이다.
그림으로 설명하면 3F의 Outer는 2F, 2F의 Outer는 1F이다.
자바스크립트의 코드에서 변수나 함수의 값을 결정하는 것을 식별자 결정(Identifier Resolution)
이라고 하는데, Outer는 식별자 결정에 도움을 준다.
만약 3F에서 puppy의 식별자를 결정하고 싶은데, 3F의 실행 컨텍스트의 환경 레코드에 puppy가 존재하지 않는다면, 2F, 2F에도 없다면 1F 까지 거슬러 올라가는 것이다.
이렇게 식별자를 결정할 때 활용하는 스코프들의 연결 리스트를 스코프 체인이라고 한다.
해당 영상을 보고 호이스팅, 스코프 체인에 대해 잘 정리된 것 같아서 두고두고 읽으려고 정리해봤는데, 앞으로도 유용하게 사용할 것 같다.