2023-04-06
실행 컨텍스트와 호이스팅
자바스크립트 핵심 개념인 실행 컨텍스트와 호이스팅에 대해 알아보자!
실행 컨텍스트
자바스크립트 코드가 평가되고 실행되는 환경
을 추상화한 개념이다.
식별자(변수)를 등록하고 선언에 따른 스코프 설정 등 실행에 필요한 모든 것을 관리한다.
실행 컨텍스트는 코드가 실행될 때 동적으로 생성되고, 콜 스택(call stack)에 쌓여 실행되는 순서에 따라 관리된다.
실행 컨텍스트는 아래와 같은 컴포넌트로 구성되어 있다.
변수 객체(Variable Environment 또는 Variable Object)
변수, 함수 선언 등과 같은 정보를 담고 있는 객체로 Lexical Environment의 상위 개념이다.
Lexical Environment와 혼용되어 사용되기도 하기 때문에 더 명확하게 구분한다면 아래와 같다
실행 컨텍스트는 변수 객체를 통해 변수 및 함수에 접근 및 관리하고,
Lexical Environment를 통해 스코프 체인을 형성하고 상위 스코프에 대한 참조가 이루어진다.
렉시컬 환경(Lexical Environment)
블록, 함수, 전역 범위 등 상위 스코프
에 대한 참조를 저장하고 관리한다.
렉시컬 환경은 선언된 위치
에 따라 스코프가 결정된다.
식별자의 스코프 체인 즉, 어디에서 해당 식별자를 찾아야 하는지를 결정하는 역할을 한다.
스코프 체인(Scope Chain):
변수 객체를 비롯하여 상위 스코프의 변수 객체들을 차례로 연결된 연결 리스트로 구성된 자료.
스코프 체인은 변수와 함수를 검색하기 위해 사용된다.
this Value(this 값)
현재 실행 중인 코드의 주체인 객체를 가리키는 값으로, 동적(호출 시점)으로 달라진다.
전역 코드에서는 전역 객체를 참조한다.
Lexical Environment 구조
환경 레코드(Environment Record)
스코프에 포함된 식별자를 등록하고 식별자에 바인딩된 값을 관리하는 저장소다.
외부 환경(OuterLexicalEnvironment)
해당 실행 컨텍스트를 생성한 상위 렉시컬 환경을 말한다.
상위 렉시컬 환경이란 전역일 수도 있고 중첩된 환경일 수도 있다.
함수가 실행될 때마다 새로운 렉시컬 환경이 생성되고 상위 환경과는 별도의 환경을 갖는다.
이때 변수에 접근하게 되면 현재 환경에서 기록을 찾고, 발견되지 않으면 전역 환경에 도달할 때까지 스코프 체이닝을 통해 참조한다.
Lexical Environment 종류
전역 렉시컬 환경(Global Lexical Environment)
전역 스코프를 나타내는 렉시컬 환경으로, 자바스크립트 프로그램이 실행될 때 전역 렉시컬 환경이 자동으로 생성된다.
전역 스코프에서 선언된 전역 변수와 전역 함수를 포함하는 객체다.
함수 환경(Function Lexical Environment)
함수 렉시컬 환경을 구성하는 컴포넌트 중 하나이며 매개변수, 아규먼트 객체,
함수 내부 지역 변수와 중첩 함수를 등록하고 저장한다.
블록 환경(Block Lexical Environment)
블록 레벨 수행문이 실행되면 렉시컬 환경을 새롭게 생성해 기존의 렉시컬 환경을 교체한다.
let, const로 선언된 식별자들은 이 환경에 저장되며 외부 렉시컬 참조는 블록 레벨이 실행되기 이전의 상위 환경을 참조한다.
실행 컨텍스트 스택 (call stack)
실행 컨텍스트의 실행 순서
를 관리한다. 엔진에 의해 코드를 평가되면 실행 컨텍스트가 생성되어 콜 스택에 추가된다.
최상단에 위치한 실행 컨텍스트는 활성화된 컨텍스트로 실행 완료시 팝되어 제거된다.
JavaScript 엔진은 싱글 스레드이기 때문에 한 번에 하나의 작업만 실행할 수 있다.
평가와 실행
모든 소스 코드는 로드 되면, 자바스크립트 엔진은 평가와 실행 과정을 나누어 처리한다.
우선 전역 코드 평가를 시작하고 실행 컨텍스트를 생성한 후, 렉시컬 환경에 식별자와 함수 등 선언문
만 먼저 등록한다.
이후 실행 과정(런타임)에 의해 순차적으로 실행된다. 이때 식별자에 값을 할당하고 함수 호출이 발생하면,
제어권이 함수 내부로 이동해 함수 내부 코드를 평가 후 실행하는 과정을 밟는다.
호이스팅(Hoisting)
호이스팅이란 해당 스코프의 최상단으로 옮겨지는 동작으로 평가 단계에서 동작한다.
따라서 식별자(var), 선언된 함수를 선언 이전에 호출해도 에러가 발생하지 않는다.