23장 : 실행 컨텍스트(1)
by 담담이담1. 소스코드의 타입
소스코드를 4가지 타입으로 구분한다.
이 4가지 타입의 소스코드는 실행 컨텍스트를 생성한다.
1)전역 코드 | "전역"에 존재하는 소스코드를 의미 전역에 정의된 함수, 클래스의 내부 코드는 포함 X |
2) 함수 코드 | "함수 내부"에 존재하는 소스코드 함수 내부의 중첩된 함수, 클래스의 내부 코드는 포함 X |
3) eval 코드 | 빌트인 전역 함수인 eval 함수에 인수로 전달되어 실행되는 소스코드 |
4) 모듈 코드 | 모듈 내부에 존재하는 소스코드 모듈 내부의 함수, 클래스의 내부 코드는 포함 X |
1) 전역 코드
전역 스코프 생성
var 키워드로 선언된 전역 변수 + 함수 선언문으로 전언된 전역 함수
=> 전역 객체(window)의 프로퍼티와 메서드로 바인딩
2) 함수 코드
지역 스코프 생성(함수 코드만이 지역 스코프를 생성한다)
지역 변수, 매개변수, arg 객체 관리
3) eval 코드
strict mode에서 독자적인 스코프 생성
4) 모듈 코드
모듈별로 독립적인 모듈 스코프 생성

===> 각 타입들의 코드들은 코드 평가 후에 실행 컨텍스트를 생성한다.
2. 소스코드의 평가와 실행
자바스크립트 엔진은 소스 코드를 2개의 과정으로 나눠 처리한다.
1) 소스코드 평가
런타임 이전을 의미한다.
실행 컨텍스트를 생성하고, 코드 중 "선언문"만 실행
식별자를 key로 실행 컨텍스트가 관리하는 스코프에 등록한다.
2) 소스코드 실행
런타임 시간을 의미한다.
선언문을 제외한 문을 실행한다.
실행에 필요한 참조 정보를 실행 컨텍스트에서 검색해서 얻는다.
3. 실행 컨텍스트의 역할
const x = 1; function foo () { const y = 2; function bar () { const z = 3; console.log(x + y + z); } bar(); } foo(); // 6
1) 전역 코드 평가
선언문만 실행
전역 변수와 전역 함수가 실행 컨텍스트의 전역 스코프에 등록됨
2) 전역 코드 실행
런타임 시작
전역 코드가 순차적으로 실행
"전역변수에 값이 할당"되고, "함수가 호출"됨
3) 함수 코드 평가
지역 변수 선언문, 매개변수가 실행되고
이를 실행컨텍스트의 지역 스코프에 등록
또한 함수 내부에서 지역변수로 사용할 수 있는
argument 객체가 생성됨
-> 이것도 지역 스코프에 등록되고,
this 바인딩도 결정됨
4) 함수 코드 실행
런타임 시작
함수 코드가 순차적으로 실행
i) 매개변수와 지역변수에 값이 할당되고,
ii)console.log 메서드가 호출됨
ii) console.log 메서드 호출
① 식별자 console을 스코프 체인에 검색
검색을 위해, 지역스코프는 전역스코프와 연결되어 있어야한다.
하지만, console 식별자는 스코프 체인에 등록되어 있지 않음
왜? window 객체의 "프로퍼티"잖아..
이는, 전역 객체의 프로퍼티가 마치 전역변수처럼
전역 스코프를 통해 검색이 가능해야한다는 걸 의미
(등록은 안되어 있는데 검색을 어떻게 해야하는지에 대한 설명은 책에 생략되어있음)
② log 프로퍼티를 검색
console 객체의 프로포타입 체인을 통해 검색함
③ 인수로 전달된 a+x+y 평가
a, x, y 식별자는 스코프 체인을 통해 검색 후
console.log(a+x+y)가 실행됨
=> 이 실행이 종료되면 함수 실행 과정이 종료되고,
함수 호출 이전으로 돌아가
전역 코드 실행을 계속한다.
5) 정리 - 실행 컨텍스트의 역할
코드를 실행하려면
1. 선언 시 식별자를 스코프를 구분해서 등록하고, 상태 변화(식별자에 바인딩 된 값의 변화)를 지속적으로 관리
2. 중첩 관계에 의한 스코프 체인 생성(상위 스코프로의 검색을 위함)
3. 현재 실행 중인 코드의 실행 순서 변경 후 다시 돌아가기(함수 호출에 의한 실행 순서 변경 등)
가 필요하며
이 역할을 바로 실행 컨텍스트가 한다.
모든 코드는 실행 컨텍스트를 통해 실행, 관리된다.
실행 컨텍스트에는 렉시컬 환경과 실행 컨텍스트 스택이 존재한다.
렉시컬 환경 - 식별자와 스코프 관리
실행 컨텍스트 스택 - 코드 실행 순서 관리
4. 실행 컨텍스트 스택
const x = 1; function foo () { const y = 2; function bar () { const z = 3; console.log(x + y + z); } bar(); } foo(); // 6
개요
실행 컨텍스트는 "스택" 자료 구조로 관리된다.
이를 실행 컨텍스트 스택이라고 한다.
(스택이란, 선입후출 개념의 자료구조로 그릇이 쌓인 더미라고 생각하면 된다.)
위 코드는 전역 코드와 함수 코드로 이뤄져있다.

1) 전역 코드의 평가와 실행
전역 코드 평가
-> 전역 실행 컨텍스트 생성
-> 실행 컨텍스트 스택에 푸시
(전역 변수 x와 전역 함수 foo는 전역 실행 컨텍스트에 등록됨)
-> 전역 코드 실행
-> 전역 변수 x에 값 할당, 전역 변수 foo 호출
2) foo 함수 코드의 평가와 실행
전역 함수 foo 호출시, 전역 코드 실행 일시 중단
코드 제어권이 foo 함수로 이동
JS엔진은 foo 함수 내부의 코드를 평가
-> foo 함수 실행 컨텍스트 생성
-> 실행 컨텍스트 스택에 푸시
(함수의 지역 변수 y와 중첩함수 bar가 foo 함수 실행 컨텍스트에 등록됨)
-> foo 함수 코드 실행
-> 지역 변수 y에 값 할당, 중첩 함수 bar 호출
3) bar 함수 코드의 평가와 실행
중첩 함수 bar 호출시, foo 함수 코드 실행 일시 중단
코드 제어권이 bar 함수로 이동
JS엔진은 bar 함수 내부의 코드를 평가
-> bar 함수 실행 컨텍스트 생성
-> 실행 컨텍스트 스택에 푸시
(함수의 지역 변수 z가 bar 함수 실행 컨텍스트에 등록됨)
-> bar 함수 코드 실행
-> 지역 변수 z에 값 할당, console.log 호출
-> bar 함수 종료
4) foo 함수 코드로 복귀
bar 함수가 종료되면 코드 제어권은 다시 foo 함수로
-> JS 엔진은 bar 함수 실행 컨텍스트를 실행 컨텍스트 스택에서 제거
-> foo 함수도 더 실행할 코드가 없으니 종료됨
5) 전역 코드로 복귀
foo 함수가 종료되면 코드 제어권은 다시 전역 코드로
-> JS 엔진은 foo 함수 실행 컨텍스트를 실행 컨텍스트 스택에서 제거
-> 더 실행할 전역 코드가 없으니 전역 실행 컨텍스트도 스택에서 제거
6) 정리
실행 컨텍스트 스택은 코드의 실행 순서를 관리한다,
소스 코드가 평가되면 실행 컨텍스트가 생성되고 스택의 최상위에 쌓인다.
이때, 스택의 최상위에 존재하는 실행 컨텍스트는 언제나
"현재 실행 중인 코드의 실행 컨텍스트"이다.
이를 "실행 중인 실행 컨텍스트"라고 부른다.

블로그의 정보
유명한 담벼락
담담이담