- 코어자바스크립트 요약 정리 (실행컨텍스트 pt.1)
@@ 오늘은 어제에 이어 코어 자바스크립트 책 중에 실행 컨텍스트 파트를 읽고 요약 정리했다. 실행 컨텍스트는 블로그 글을 읽거나 유어클래스 수업 파트에서 배운 적이 있고, 디버거를 통해 어느정도 이해했다고 생각한 내용이었다. 오늘은 그보다 더 자세하게 내용을 살펴봤는데, 아는 내용을 다시 재정비하는 느낌이라서 책 내용이 더 재미있게 느껴졌다. lexical environment, 변수 정보, this 등 실행 컨텍스트에 담기는 정보에 대해 살펴보았고, 스택, 큐의 구조 및 방식에 대해서 알아보았다.
variable environment 와 lexical environment가 구분이 잘 안됐고, 비슷한 이야기라고 생각했는데 variable은 최초 실행시의 스냅샷을 유지한 다는 점을 새롭게 배우게 됐다. 이를 그대로 lexical environment가 복사해서 lexical에서 활용한다는 점이 새롭게 알게 된 내용이었고,
lexical environment에 대한 어휘 풀이 부분이 뭐 다 통용되는 것은 아니어도 이해를 돕는 의미에서 좋았던 것 같다.
호이스팅을 다 안다고 생각했는데, 실행 컨텍스트와 관련지어서 다시 살펴보니 또 새롭게 느껴졌다. 콘솔에 찍히는 값을 예측 못했던 것 보니 호이스팅도 내가 아직은 개념 정비가 완벽히 안된 모양이다.
실행할 코드에 제공할 환경 정보를 모아놓은 객체를 뜻한다.
코드를 실행할 때 환경 정보들을 모아 컨텍스트를 구성하고 이를 콜 스택에 쌓아 가장 위에 있는 컨텍스트 관련 코드를 실행하는 식으로 코드 환경 및 순서를 보장
전역 공간은 자동 생성
보안상 문제로 사용이 자제되는 eval()함수도 따로 실행 컨텍스트를 가진다.
이를 제외하곤 실행 컨텍스트를 구성하는 방법은 함수를 실행하는 것이다
스택
출입구가 하나인 깊은 우물 같은 데이터 구조.
스택이 담을 수 있는 한계를 넘어설 때 스택 오버플로우라는 에러를 던진다. (선입후출)
큐
양쪽이 모두 열려있는 파이프 구조
양쪽 모두 입력과 출력이 가능한 큐도 있으나, 보통은 한쪽은 입력만 한쪽은 출력만 담당하는 구조를 뜻한다. (선입선출)
실행 컨텍스트 순서
처음 자바스크립트 코드 실행 순간 - 전역 컨텍스트가 콜 스택에 담긴다.
함수 실행의 순간 자바스크립트 엔진은 해당 함수에 대한 환경 정보를 수집해서 함수의 실행 컨텍스트를 생성한 후 콜 스택에 담는다. 함수 내부의 코드를 실행하기 위해서 전역 컨텍스트 관련 코드 실행을 일시 중지하고, 함수 내부 코드들을 순차적으로 실행한다.
자바스크립트 엔진은 해당 컨텍스트 관련 코드를 실행하는데 필요한 환경정보를 수집해 실행 컨텍스트 객체에 저장한다.
실행 컨텍스트 환경 정보
VariableEnvironment
현재 컨텍스트 내의 식별자들에 대한 정보 , 외부 환경 정보
최초 실행시의 스냅샷을 유지한다.
environmentRecored, outerEnvironmentReference
LexicalEnvironment
처음에는 VariableEnvironment 와같지만 변경 사항이 실시간 반영된다.
environmentRecored, outerEnvironmentReference.
Lexical(사전적인) - 식별자들에 대한 정보, 외부정보가 어떻게 돼있는지 저장돼있는 사전과 같이, 컨텍스트를 구성하는 환경 정보들을 담고 있다.
environmentRecord
현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장된다. 매개변수 식별자, 선언 함수, var 로 선언된 변수의 식별자 등이 식별자에 해당
전역 실행 컨텍스트는 변수 객체를 생성하는 대신 자바스크립트 구동 환경이 별도로 제공하는 객체 즉 전역 객체를 활용. 전역 객체엔 window, Node.js의 global객체 등이 있다. 이들은 내장 객체가 아닌 호스트 객체로 분류된다.
변수 정보를 수집하는 과정이 선행 되고, 코드를 실행한다.코드를 실행하기 전에 자바스크립트 엔진은 이미 해당 환경에 속한 코드의 변수명들을 모두 알고 있다. (호이스팅)
변수는 선언부만 끌어올리는 반면, 함수 선언은 함수 전체를 끌어올린다.
함수 선언문과 함수 표현식
- 함수 표현식 - 기명함수 표현식, 익명함수 표현식
기명함수 표현식을 쓰더라도 함수명으로 함수를 호출할 수 없다는 점을 기억해야한다. 이전에 익명함수 표현식이 어떤 함수 인지 추적하기 위해 쓰임.
함수 선언문의 위험성.
호이스팅 때문에 나중에 선언된 함수가 그 이전 함수를 덮어써버린다.(위의 코드들에서조차도)
스코프, 스코프 체인
ES5까지는 전역공간을 제외하고서는 오직 함수에 의해서만 스코프가 생성된다.
스코프 체인
식별자의 유효범위를 안에서부터 바깥으로 차례로 검색해 나가는 것(LexicalEnvironment 의 두번째 수집자료 outerEnvironmentReference)
outerEnvironmentReference는 호출된 함수가 선언될 당시에 LexicalEnvironment를 참조한다.
예를 들어 a함수 안의 b함수 안의 c함수의 경우, c 함수의 outerEnvironmentReference 는 함수 b의 lexicalEnvironment 를 참조한다. (outerEnvironmentReference 는 연결 리스트 형태를 띈다)
각 outerEnvironmentReference는 선언된 시점의 LexicalEnvironment만 참조한다.
여러 스코프에서 동일한 식별자를 선언한 경우 무조건 스코프 체인 상에서 가장 먼저 발견된 식별자에만 접근이 가능하다.
크롬 개발자 도구에서는 함수 출력 결과를 조회해보면 함수 내부에서 호출할 외부 변수들의 정보만 보여준다. 더 자세하게 정보를 알고 싶으면 debugger를 이용해야 한다.