본문 바로가기

FrontEnd/Javascript

실행 컨택스트

참조: https://www.youtube.com/watch?v=EWfujNzSUmw

 

(복습. Closure함수: 자신이 선언 되었을 때 렉시컬 환경(렉시컬 스코프)을 기억하는 함수)

(내생각)실행컨텍스트(환경), 스코프가 같은 의미로 쓰일수 있다. 
(내생각)실행컨텍스트: 코드 실행에 필요한 환경(조건이나 상태)을 모아둔 객체(즉 스코프역시 코드 실행에 필요한 조건이나 상태를 모아둔 영역이므로 스코프가 실행컨텍스트와 같은 의미일 수 있는것이다)

요약: 실행 컨텍스트이란? 코드를 실행하는데 필요한 환경을 제공하는 객체.  여기서 환경이란 코드 실행에 영향을 주는 조건이나 상태를 의미함.  식별자 결정을 더욱 효율적으로 하기 위한 수단으로써 필요한 정보를 한곳에 모아 제공하는 객체.


스코프 체인이란?: 스코프들의 연결리스트임!! 식별자를 결정할 때 활용하는 스코프들의 연결리스트
(내 생각에는 rough하게 scope=실행 컨텍스트=환경 이다)


바인딩(Binding)이란 식별자와 값(인스턴스)을 연결하는 것이다. 스코프체인이 전역스코프를 가리키는 전역객체를 바인딩하고 함수 outerFunc의 스코프를 가리키는 함수 outerFunc의 활성 객체를 반인딩하고... 이렇게 스코프와 객체를 바인딩한다는 의미는 각각의 스코프가 식별자의 역할을 하고 각각의 객체가 값의 역할을 한다는 것이다. 

스코프체이닝이란? 식별자를 결정하기 위해 활용하는 스코프들의 연결리스트
콜스텍에서는 가장 최근에 실행된 실행컨텍스트만 활성화됨. 콜스텍(Call stack, 실행컨텍스트)은 자바의 함수스텍이랑 똑같다. 가장 최근에 실행된 컨텍스트만 활성화되고 함수가 종료되면 해당 실행컨텍스트도 사라진다.

 

1.  실행컨텍스트의 환경 레코드 관점에서 호이스팅 이해하기:

로딩시점에 Js engine이 먼저 코드를 스켄하면서 변수정보를 실행컨텍스트의 환경 레코드에 기록함. Environment record란 식별자와 식별자에 연결된 값을 기록하는 객체이다. 환경레코드에 변수가 어떻게 기록되는지만 잘 알아도 호이스팅을 바로 이해할 수 있다.

 

스캔하고 생성(실행 컨텍스트 생성, 선언문만 실행,환경레코드에 undefined라는 값으로 저장)하는 단계를 생성단계라고한다. 이후 선언문 외의 나머지 코드를 순차적으로 실행하는데 이 단계를 실행 단계라고 함. 연속적슬라이드를 보고 싶다면 https://www.youtube.com/watch?v=EWfujNzSUmw

 

var과는 다르게 const, let같은 경우 선언문 이전에 변수의 값을 읽어들이려 하면 Reference Error가 발생함(Type Error가 발생하는 것이 아님). 이유는 실행컨텍스트안의 환경 레코드에 TVChannel이라는 변수를 저장은 해두었지만 값을 초기화하진 않아서, 값 저장을 위한 메모리 공간은 마련해 두지 않아서 그런것임.

var 키워드로 변수를 선언한 경우 선언과 초기화가 동시에 이루어짐(우선은 undefined로 초기화됨). 하지만 let, const로 변수를 선언한 경우는 선언만 환경 레코드에 기록되고(이때 초기화는 이루어지지 않아 값을 위한 메모리 공간조차 마련되어 있지 않은 상태임) 초기화는 선언문에 가서 이루어짐.

이제 함수 호이스팅에서 대해 알아보자!

JS에서는 함수를 객체취급하여 변수에 함수를 담을 수 있다.

var키워드에 화살표 함수를 담아 선언문 이전에 실행하려고 하면 환경레코드에 기록되어 있는 study의 값은 undefined이고 undefined라는 데이터타입은 함수와 달리 호출될 수 없기 때문에 TypeError가 발생하는 것이다!!(즉, undefined( ) 꼴이 되는 것이므로 호출할 수 없는 것임)
위와 모든 조건이 같고 var만 const로 바꾼다면 환경 레코드에 변수는 선언되었지만 그에 할당된 값이존재하지 않아(값을 위한 메모리공간 존재하지 않음)Reference Error가 발생하는 것임. 이와 같이 함수 표현식은 변수 호이스팅과 동일하게 동작한다(쉽게 생각해서 함수를 변수에 담고 있으므로 벼수 호이스팅과 동일하게 동작한다고 보면된다)

 

함수선언문으로 함수를 선언한 경우에는 js엔진이 코드로딩 시점에 실행컨텍스트의 환경 레코드에 완성된 함수객체를 생성해서 기록한다.즉, 선언 전에도 함수를 자유롭게 사용할 수 있는것.

 

var 키워드로 함수 표현식을 작성하고 선언문 이전에 호출할 경우 TypeError가 발생. let, const키워드로 함수 표현식을 작성하고 선언문 이전에 호출할 경우 ReferenceError가 발생. 함수 선언문을 선언문 이전에 호출할 경우 아무 문제 없음.

 

==========================================================================================

Outer Environment Reference로 스코프 체이닝을 이해해 보자!

outer의 정식명칭은 Outer Environment Reference이다. 바깥쪽의 Lexical Scope를 가리킨다(즉 바깥쪽의 Execution Context를 가리키는 것이라고 편하게 생각).

(복습. 스코프 체인이란? 식별자를 결정하기 위해 이용되는 스코프들의 연결리스트)

내 생각에는 outer Environment Reference역시 환경 레코드에 저장될 것이다.

 

실행컨텍스트의 종류가 3가지가 있다는 말(사실 3개보다 많음. 아래 그림 참조). 물론 3종류의 실행컨텍스트 모두 동일한 Call Stack에 쌓임. Activation Object=활성화 객체... 아, 이게 DeepDive에서 설명한 활성화 객체이다. 이 활성화 객체를 위한 컨텍스트가 Function Execution context이다.

 

 

실행컨텍스트는 크게 생성단계(코드로딩, 준비단계)와 실행단계(코드를 실행하는 단계)로 나뉘어 진다.

아래 생성단계 잘 봐놓자. 아래 그림을 설명해 준다.

생성단계(Creation phase에서 위 그림에 있는 this, schope chain, Global Object, Activation Object가 형성되는 것임

 

생성단계(Creation phase)에서 일어나는 일들이다. 전역 객체, 활성화 객체, this가 형성되고 스코프 체인(전체 코드를 훓으면서 스코프 체인이 발생하는 것!!!즉 Outer environment reference의 값을 지정하는 것임)이 형성된다.
실행단계(Execution phrase)에서 일어나는 일들.