자바스크립트 엔진은 2개의 과정으로 나누어 소스코드를 처리합니다.
모든 소스코드는 실행에 앞서 평가 과정을 거치고 실행하기 위한 준비를 합니다.
평가 과정에서는 실행 컨텍스트를 생성하고 변수, 함수 등의 선언문을 먼저 실행합니다.
여기서 생성된 변수나 함수의 식별자를 키로 사용해서 실행 컨텍스트가 관리하는 스코프에 등록합니다.
이때 소코프는 렉시컬 환경의 환경 레코드를 의미합니다.
평가 과정이 끝나면, 앞서 실행했던 선언문을 제외한 나머지 소스코드가 순차적으로 실행됩니다. 이때가 '런타임'이 시작되는 것입니다. 이때 소스코드에 실행에 필요한 정보들(변수, 함수 등)을 실행 컨텍스트가 관리하는 스코프에서 검색해서 취득합니다. 그리고 변수 값의 변경 등의 실행 결과를 다시 실행 컨텍스트가 관리하는 스코프에 등록합니다.
그렇다면 만약 전역과 함수(로컬) 스코프가 있다면 어떤 순서로 자바스크립트 엔진은 동작할까요?
전역 코드 평가 과정을 거치면서 변수와 함수 선언문만 먼저 실행합니다. 이 결과로 생성된 전역 변수와 전역 함수는 실행 컨텍스트가 관리하는 전역 스코프에 등록됩니다. 이때 전역 변수와 전역 함수는 각각 전역 객체의 프로퍼티와 메소드가 되는 것입니다.
평가 과정이 끝나고 런타임이 시작되어 전역 코드가 순차적으로 실행됩니다. 이때 전역 변수에 값이 할당되고 함수가 호출되는 것입니다. 함수가 호출되면 순차적으로 실행되던 전역 코드의 실행을 일시 중단하고 코드 실행 순서를 변경하여 함수 내부로 진입합니다.
함수로 내부로 진입하면 함수 내부의 코드 평가 과정을 거칩니다. 이때 매개변수와 지역 변수 선언문만 먼저 실행되고, 여기서 생성된 매개변수와 지역 변수는 실행 컨텍스트가 관리하는 지역 스코프에 등록됩니다. 또한 함수 내부에서 지역 변수로 사용할 수 있는 arguments 객체가 생성되어 지역 스코프에 등록되고 this 바인딩도 결정됩니다.
함수 코드 평가 과정이 끝나면 런타임이 시작되어 함수 코드가 순차적으로 실행됩니다. 이때 매개변수와 지역 변수에 값이 할당되고 console.log 메소드가 호출됩니다. 이때 log 메소드에 인수로 전달된 a+x+y
표현식이 평가되며, 스코프 체인을 통해 a, x, y 식별자를 각각 검색합니다. log 메소드의 실행이 종료되면 함수 호출 이전으로 되돌아가 전역 코드 실행을 계속해서 진행합니다.
위와 같은 실행 과정이 가능하기 위해서는 '스코프, 식별자, 코드 실행 순서'에 대한 관리가 필요합니다.
선언에 의해 생성된 '변수, 함수, 클래스' 등의 모든 식별자를 스코프를 구분하여 등록하고, 상태 변화를 지속적으로 관리해야 합니다.
스코프 간의 중첩 관계에 의해 스코프 체인을 형성해야 합니다. 따라서 스코프 체인을 통해서 하위 스코프에서 상위 스코프로 이동하며 식별자를 검색할 수 있어야 합니다.
함수 호출에 의해 함수 내부로 코드 실행 순서가 진입하거나, 종료 후 다시 이전 위치로 되돌아갈 수 있어야 합니다.
이러한 조건들을 유지할 수 있도록 모든 것을 관리하는 것이 '실행 컨텍스트'입니다.
식별자를 등록하고 식별자를 관리하는 스코프와 코드 실행 순서 관리를 구현한 내부 메커니즘으로, 모든 자바스크립트 코드는 실행 컨텍스트를 통해 실행되고 관리됩니다.
식별자와 스코프는 실행 컨텍스트의 '렉시컬 환경'으로 관리하고, 코드 실행 순서는 실행 컨텍스트 '스택'으로 관리합니다.
참조링크
모던 자바스크립트 Deep Dive