이 포스팅은 이전 포스트(자바스크립트 동작방식)를 읽으시면 이해하시는데 도움이 됩니다.
자바스크립트는 싱글스레드로 실행 되며 함수들을 콜 스택에 쌓아 관리하게 되는데 이 때 콜 스택에는 함수 객체 자체가 저장되지 않고, 대신 함수의 호출과 관련된 실행 컨텍스트가 저장된다.
실행 컨텍스트는 현재 실행 중인 코드 블록(함수, 전역 코드 등)의 실행 정보를 담고 있으며, 변수 환경, 렉시컬 환경, this 바인딩 등의 정보를 포함한다. 이 정보는 코드의 실행을 관리하며, 콜 스택에 쌓여 순차적으로 처리된다.
Lexcical Environmet는 자바스크립트 중첩 구조(lexical nesting structure of ECMAScript code)를 기반으로 변수 혹은 함수와 식별자의 연관성을 정의하는 명세 유형이다. (함수가 정의된 구문적 상황(lexical context)에 엮여있는 변수나 함수들을 담은 명세서)
렉시컬 환경은 환경 레코드와 외부 렉시컬 환경에 대한 참조로 이루어 진다. 환경 레코드에 let, const로 선언한 변수들(var 변수들은 global에 있음)이나 메소드등이 담겨 있다. 만약 함수에서 환경 레코드에 없는 변수들에 접근하려고 할 경우 자바스크립트는 외부 렉시컬 환경에 대한 참조를 확인한다.(스코프 체인이 생성되고, 함수와 코드블록에서 외부 스코프의 변수에 접근할 수 있는 이유)
Scope
해당 Lexical context에서 접근 가능한(locally) 식별자들의 집합
실행 컨텍스트는 변수환경, 렉시컬 환경, this 바인딩을 포함한 객체이다. 이 객체는 자바스크립트 코드의 실행 순서를 관리하는 콜 스택에 쌓이며(push) 선입후출의 원칙에 따라 실행이 완료 되면 제거(pop) 된다.
이 과정에서 여러 중요한 개념들이 나오는데 하나는 렉시컬 환경의 구성요소인 환경 레코드에 담긴 변수들의 집합이 스코프가 된다.
근데 자바스크립트 함수는 조금 특별해서 함수가 선언될 당시의 렉시컬 환경을 기억하여, 다른 곳에서 호출 되더라도 선언 될 당시의 렉시컬 환경에 의한 접근 가능한 변수들에 접근하고 변경할 수 있는데 이를 클로저라고 한다.
또한 실행 컨텍스트는 시점에 따라 실행 컨텍스트가 생성 될 시점(자바스크립트가 코드 블록을 읽기 전)은 creation phase를 갖고 실행 될때 execution phase(위에서 말한 실행 컨텍스트는 execution phase를 기준으로 생각할 수 있다.)를 갖는데, 자바스크립트가 코드 블록을 아직 읽기 전, 실행 컨텍스트에 코드블록에 선언된 변수나 함수들을 메모리 할당하는데 이를 호이스팅이라고 한다.