CH23. 실행컨텍스트
23.1 소스코드의 타입
23.2 소스코드의 평가와 실행
- 소스 평가 과정에서는 실행 컨텍스트를 생성하고
변수, 함수 등의 선언문만 먼저 실행하여 생성된 변수나 함수 식별자를 키로 실행 컨텍스트가 관리하는 스코프에 등록함
23.3 실행 컨텍스트의 역할
1. 전역 코드 평가
- 전역 코드 실행하기 앞서 전역 코드 평가 과정을 거침
- 소스코드 평가 과정에서는 선언문만 먼저 실행됨
- var 키워드로 선언된 전역 변수와 함수 선언문으로 정의된 전역 함수는 전역 객체의 프로퍼티와 메서드가 됨
2. 전역 코드 실행
- 런타임이 시작되어 전역 코드가 순차적으로 실행되기 시작함
- 전역 변수에 값이 할당되고 함수가 호출됨
3. 함수 코드 평가
- 함수 호출에 의해 코드 실행 순서가 변경되어 함수 내부로 진입하면 함수 내부의 문들을 실행하기에 앞서 함수 코드 평가 과정을 거침
- 매개변수와 지역 변수 선언문이 먼저 실행되고, 그 결과 생성된 매개변수와 지역 변수가 실행 컨텍스트가 관리하는 지역 스코프에 등록됨
- 함수 내부에서 지역 변수처럼 사용할 수 있는 arg 객체가 생성되어 지역 스코프에 등록되고 this 바인딩도 결정됨
4. 함수 코드 실행
- 런타임이 시작되어 함수 코드가 순차적으로 실행되기 시작함
- 매개변수와 지역변수에 값이 할당되고 console.log 메서드가 호출됨
23.4 실행 컨텍스트 스택
const x = 1;
function foo(){
const y = 2;
function bar() {
const z = 3;
console.log(x + y + z);
}
bar();
}
foo();
- 먼저 전역코드를 평가하여 전역 실행 컨텍스트를 생성
- 함수가 호출되면 함수 코드를 평가하여 함수 실행 컨텍스트를 생성
- 이때 생성된 실행 컨텍스트는 스택 자료구조로 관리됨 -> 실행 컨텍스트 스택
23.5 렉시컬 환경
렉시컬 환경?
- 식별자와 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 참조를 기록하는 자료구조로 실행 컨텍스트를 구성하는 컴포넌트
- 키와 값을 갖는 객체 형태의 스코프(전역, 함수, 블록 스코프)를 생성하여 식별자 키로 등록하고 식별자에 바인딩된 값을 관리함
렉시컬 환경은 두 개의 컴포넌트로 구성됨
1. 환경 레코드
: 스코프에 포함된 식별자를 등록하고 등록된 식별자에 바인딩된 값을 관리하는 저장소
: 환경 레코드는 소스코드의 타입에 따라 관리하는 내용에 차이가 있음
2. 외부 렉시컬 환경에 대한 참조
: 상위 스코프를 가리킴
: 외부 렉시컬 환경에 대한 참조를 통해 단방향 링크드 리스트인 스코프 체인을 구현함
23.6 실행 컨텍스트의 생성과 식별자 검색 과정
23.6.1 전역 객체 생성
- 전역 코드가 평가되기 이전에 생성됨
23.6.2 전역 코드 평가
- 소스코드가 로드되면 자바스크립트 엔진은 다음과 같은 순서로 전역 코드를 평가함
23.6.3 전역 코드 실행
23.6.4 foo 함수 코드 평가
- foo 함수가 호출되면 전역 코드의 실행을 일시 중단하고 foo 함수 내부로 코드의 제어권이 이동함
- 아래와 같은 순서로 진행
23.6.5 foo 함수 코드 실행
- 식별자 결정을 위해 실행 중인 실행 컨텍스트의 렉시컬 환경에서 식별자를 검색하기 시작함
23.6.6 bar 함수 코드 평가
- bar 함수가 호출되면 bar 함수 내부로 코드의 제어권이 이동함
23.6.7 bar 함수 코드 실행
! 다음 코드의 실행순서
console.log(a + b + x + y + z);
1. console 식별자 검색
2. log 메서드 검색
3. 표현식 a + b + x + y + z의 평가
4. console.log 메서드 호출
23.6.8 bar 함수 코드 실행 종료
- console.log 메서드가 호출되고 종료하면 더는 실행할 코드가 없으므로 bar 함수 코드의 실행이 종료됨
- bar 함수 실행 컨텍스트가 소멸되었다 하더라도 만약 bar 함수 렉시컬 환경을 누군가 참조하고 있다면 bar 함수 렉시컬 환경은 소멸하지 않음
23.6.9 foo 함수 코드 실행 종료
- bar 함수가 종료하면 더 이상 실행할 코드가 없으므로 foo 함수 코드의 실행이 종료됨
- 실행 컨텍스트 스택에서 foo 함수 실행 컨텍스트가 팝되어 제거되고 전역 실행 컨텍스트가 실행 중인 실행 컨텍스트가 됨
23.6.10 전역 코드 실행 종료
foo 함수가 종료되면 더 실행한 전역 코드가 없으므로 전역 코드의 실행이 종료되고 전역 실행 컨텍스트도 실행 컨텍스트 스택에서 팝되어 실행 컨텍스트 스택에는 아무것도 남아있지 않게 됨
23.7 실행 컨텍스트와 블록 레벨 스코프
let x = 1;
if (true) {
let x = 10;
console.log(x);
}
console.log(x);
- if 문의 코드 블럭이 실행되면 if 문의 코드 블록을 위한 블록 레벨 스코프를 생성해야 함
- 이를 위해 선언적 환경 레코드를 갖는 렉시컬 환경을 새롭게 생성하여 기존의 전여 렉시컬 환경을 교체함
- 이때 새롭게 생성된 if 문의 코드 블록을 위한 렉시컬 환경의 외부 렉시컬 환경에 대한 참조는
if문이 실행되기 이전의 전역 렉시컬 환경을 가리킴
CH13. 스코프
13.1 스코프란?
- 변수는 자신이 선언된 위치에 의해 자신이 유효한 범위가 결정됨
- 변수뿐만 아니라 모든 식별자 해당
- 스코프는 식별자가 유효한 범위
- 자바 스크립트 엔진이 식별자를 검색할 때 사용하는 규칙
! var 키워드로 선언한 변수의 중복 선언
- var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언이 허용됨
- 의도치 않게 변수값이 재할당되어 변경되는 부작용을 발생시킴
- 하지만 let이나 const 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용하지 않음
13.2 스코프의 종류
13.2.1 전역과 전역 스코프
- 전역변수는 어디서든지 참조 가능
- 전역에 변수를 선언하면 전역 스코프를 갖는 전역변수
13.2.2 지역과 지역 스코프
- 지역?
: 함수 몸체 내부
- 지역 변수는 자신의 지역 스코프와 하위 지역 스코프에서 유효함
13.3 스코프 체인
- 함수는 중첩될 수 있으므로 함수의 지역 스코프도 중첩될 수 있음
: 즉, 스코프가 함수의 중첩에 의해 계층적 구조를 갖게됨
- 이처럼 모든 스코프는 하나의 계층적 구조로 연결됨
- 모든 지역 스코프의 최상위 스코프는 전역 스코프
- 변수를 참조할 때, 자바 스크립트 엔진은 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색함
13.3.1 스코프 체인에 의한 변수 검색
- 상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조할 수 있지만,
- 하위 스코프에서 유효한 변수를 상위 스코프에서 참조할 수 없음
13.3.2 스코프 체인에 의한 함수 검색
- 스코프를 '변수를 검색할 때 사용하는 규칙'이라고 표현하기 보다는 '식별자를 검색하는 규칙'이라고 표현하는 편이 더 적합함
13.4 함수 레벨 스코프
- var 키워드로 선언된 변수는 오로지 함수의 코드 블록(함수 몸체)만을 지역 스코프로 인정함
- 이러한 특성을 함수 레벨 스코프라고 함
var x = 1;
if (true) {
var x = 10;
}
console.log(x); //10
// 의도치 않게 변수 값이 변경되는 부작용
13.5 렉시컬 스코프
var x = 1;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x);
}
foo();
bar();
-> bar 함수는 전역에서 정의된 함수,
- 함수 선언문으로 정의된 bar 함수는 전역 코드가 실행되기 전에 먼저 평가되어 함수 객체를 생성함
- 이때 생성된 bar 함수 객체는 자신이 정의한 스코프, 즉 전역 스코프를 기억함
- bar 함수가 호출되면 호출된 곳이 어디인지 관계없이 언제나 자신이 기억하고 있는 전역 스코프를 상위 스코프로 사용함
-> 따라서 위 예제를 실행하면 전역 변수 x의 값 1을 두 번 출력하는 결과
'2022-2 웹개발 스터디' 카테고리의 다른 글
[모던 JS] CH16 프로퍼티 어트리뷰트, CH17 생성자 함수에 의한 객체 생성 (0) | 2022.10.04 |
---|---|
[모던 JS] CH14 전역 변수의 문제점, CH15 let, const 키워드와 블록 레벨 스코프 (1) | 2022.10.03 |
[코드] (0) | 2022.09.21 |
[모던 JS] CH12. 함수 (1) | 2022.09.20 |
[모던 JS] CH10 객체 리터럴, CH11 원시 값과 객체의 비교 (0) | 2022.09.20 |