오늘은 실행 컨텍스트, 호이스팅, 스코프 체이닝을 공부해 볼 것이다!✍
실행 컨텍스트는 실행 컨텍스트란 실행 코드에 제공할 정보들을 모아 놓은 객체이다.
자바스크립트는 콜 스택(참조하기)에 전역 실행 컨텍스트을 담고, 전역에서 func A를 호출하면 A가 그 위에 쌓이고 A에서 func B를 호출하면 그 위에 B가 쌓이면서 스택구조로 구성된다.
이후에 스택구조로 B의 실행이 종료되면, B의 실행 컨텍스트가 사라지고 A를 수행하고 A의 실행 컨텍스트가 사라지는 식으로 작동한다.
실행 컨텍스트안에는 크게 Variable Environment, Lexical Environment, ThisBinding 이 세 가지가 존재한다.
Lexical Environment 의 내부에는 Envrionment Record 와 Outer Environment Reference 의 객체를 가지고 있으며, 위의 Call stack 그림에 각 실행컨텍스트 박스 안에 들어있는 Record와 Outer를 의미한다.
호이스팅은 선언문이 마치 최상단에 끌어올려지는 듯한 현상이다.
쉽게 말하면, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미한다.
실행 컨텍스트안에 환경 레코드(Envrionment Record) 는 식별자와 식별자에 바인딩된 값을 기록해두는 객체이다.
이 환경 레코드에 변수가 어떻게 저장되는지를 확인하며 호이스팅현상을 이해하자.
1. 변수 호이스팅(Variable Hoisting)
우선 위에서 보았듯, 자바스크립트는 전역 실행 컨텍스트를 우선적으로 호출한다. 그리고 전체 코드를 스캔하며, 먼저 선언할 것 이있는지 확인하고 있다면 먼저 선언을 한다.
다음과 같은 코드가 있다. 이것을 실행해보자.console.log(person); var person = "칸정우"; //let, const console.log(person);
전역 컨텍스트는 person이라는 변수를 확인하고 먼저 선언을 하는데, 이 선언 내용은 환경 레코드에 기록한다. (생성 단계)
그리고 이어서 코드를 순차적으로 실행하는데, 필요에 따라 생성단계에서 기록한 정보를 참조하거나 업데이트를 한다.(실행단계)
이제 실행단계에 따라, person을 출력하기 위해 환경 레코드에 있는 person을 참조한다.
다만 이때 변수를 선언한 방식에 따라 환경 레코드에 다르게 기록되어진다. var의 경우엔 undefined값 바인딩 및 메모리할당(초기화), let과 const의 경우에는 값을 바인딩하지 않고 메모리만 할당하기에 error가 발생한다.(선언)
이렇듯 변수가 선언되기 이전에 메모리를 미리 할당하는 것을 변수호이스팅이라고 한다.
2. 함수 호이스팅(Variable Hoisting)
함수 호이스팅이란 위에서 본 변수호이스팅과 유사하다. 다음의 코드를 보자.
A(); function A(){ //var,let,const = () =>{} console.log("hi") }
함수 표현식(var, let, const를 이용)을 사용하게 되면, 변수 호이스팅때와 동일하게 환경 레코드에 선언이 되고, error를 발생시키며
함수 선언문(function)을 이용하면 f{}로 바인딩되어 초기화된다.
실행 컨텍스트안에 외부 환경 참조(Outer Environment Reference)는 바깥(이전) Lexical Environment(정적 환경)를 가리킨다.
자바스크립트에서는 동일한 이름의 변수나 함수가 존재할 때, 어떤 것을 값으로 결정할지 고민하는 데, 이것을 식별자 결정이라고 한다.
다음의 코드를 보며 자바스크립트가 어떻게 외부 환경 참조를 이용하여 의사결정을 하는지 확인해보자.
const person = "칸정우"; const A = () =>{ const person = "blackeichi"; const B = () =>{ const Food = "pizza" console.log(Food); console.log(Youtube); console.log(person); } B(); }; A();
위의 코드를 작동하면 Call Stack에
B함수 실행컨텍스트
ㅡㅡㅡㅡㅡㅡㅡㅡㅡ
A함수 실행컨텍스트
ㅡㅡㅡㅡㅡㅡㅡㅡㅡ
전역 실행 컨텍스트
이렇게 쌓이게 되고 우선 B 실행 컨텍스트가 활성화 되며 이에 pizza가 출력이 된다. 그리고 Youtube를 출력해야 하는데, B 실행컨텍스트 안에 환경레코드에 Youtube라는 변수가 존재하지 않는다. 이 때 자바스크립트는 외부 환경 참조가 가리키는 바깥 렉시컬 환경(A 실행 컨텍스트)으로 가서 Youtube를 찾기 시작하고, A에서도 찾지 못하면 다시 A의 외부 환경 참조가 가리키는 곳(전역 실행 컨텍스트)으로 가서 Youtube를 찾는다. 하지만 전역에도 Youtube는 존재하지 않으므로 error를 출력한다.
person을 출력할 때는 외부 환경 참조가 가리키는 A로 가면 바로 찾을 수 있기 때문에 전역까지 가지 않고 blackeichi를 출력하게 된다.
식별자를 찾을 때까지 상위로 이동하는 이러한 현상을스코프 체이닝
이라고 하며, 식별자를 결정할 때 활용하는 스코프들의 연결리스트를스코프 체인
이라고 한다.
JeungJoo Lee - [JS] 실행 컨텍스트
[10분 테코톡] 💙 하루의 실행 컨텍스트