실행 컨텍스트 : 자바스크립트의 동작 원리를 담고 있는 핵심 개념
실행 컨텍스트 : 소스코드를 실행하는데 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역
실행 컨텍스트를 이해하면 알 수 있는 것
- js가 스코프를 기반으로 식별자와 식별자에 바인딩된 값(식별자 바인딩)을 관리하는 방식
- 호이스팅이 발생하는 이유
- 클로저의 동작 방식
- 태스트 큐와 함께 동작하는 이벤트 핸들러
- 비동기 처리의 동작 방식
(나는 아직 모름;; 차차 알아가자)
4가지 소스 코드 타입
타입을 구분하는 이유는 소트코드의 타입에 따라 실행 컨텍스트를 생성하는 과정과 관리하는 내용이 다르기 떄문에 구분하는 것이다.
📌 전역 코드
- 전역코드는 전역 스코프를 생성한다.
- var 키워드로 생성된 전역 변수, 함수 선언문으로 정의된 전역 함수를 전역 객체의 프로퍼티와 메서드로 바인딩 된다.
- 전역 변수와 전역 함수를 참조하기 위해 전역 실행 컨텍스트가 생성되어 전역 객체의 프로퍼티를 탐색하여 값을 반환한다.
📌 함수 코드
- 함수 코드는 지역 스코프를 생성한다.
- 지역 변수, 매개변수, arguments 객체를 관리해야한다.
- 지역 스코프는 항상 전역 스코프와 연결된다.
- 지역 스코프와 전역 스코프를 연결하기 위해 함수 코드가 평가 되면 함수 실행 컨텍스트가 생성되어, 이 컨텍스트는 함수 내부에서 선언된 변수와 상위 스코프(외부 렉시컬 환경)에 대한 참조를 포함한다. ⇒ 이 구조가 스코프 체인을 형성해 변수 참조 시 상위 스코프까지 접근할 수 있도록 만든다.
🔸 스코프 체인은 밑에서 나오지만 간단하게 설명하면 스코프가 계층적으로 연결된 것!
📌 eval 코드
- eval 코드는 strict mode에서 자신만의 독자적인 스코프를 생성
- 이를 위해 eval 코드가 평가되면 eval 실행 컨텍스트가 생성된다.
📌 모듈 코드
- 모듈 코드는 모듈별로 독자적인 모듈 스코프를 생성(import로 가져온 외부 모듈의 식별자는 이 환경에 포함)
- 이를 위해 모듈 코드가 생성되면 모듈 실행 컨텍스트가 생성된다. </aside>
소스코드의 평가와 실행
자바스크립트 엔진은 소스코드 평가, 소스코드 실행 과정으로 나누어 처리한다.
📌 소스코드 평가 과정 : 실행 컨텍스트를 생성하고 변수, 함수 등의 선언문만 먼저 실행하여 생성된 변수나 함수 식별자를 키로 실행 컨텍스트가 관리하는 스코프(렉시컬 환경의 환경 레코드)에 등록
📌 소스코드 실행 과정(런타임): 선언문을 제외한 소스코드가 순차적으로 실행, 변수나 함수의 참조와 같이 소스코드의 실행에 필요한 정보는 실행 컨텍스트가 관리하는 스코프에서 검색해서 취득한다.
변수 값의 변경 등 소스코드의 실행 결과는 다시 실행 컨텍스트가 관리하는 스코프에 등록
실행 컨텍스트 : 소스코드를 실행하는 데 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역.
- 실행 컨텍스트는 식별자(변수, 함수, 클래스 등의 이름)를 등록하고 관리하는 스코프와 코드 실행 순서 관리를 구현한 내부 매커니즘으로 모든 코드는 실행 컨텍스트를 통해 실행되고 관리된다.
- 각 실행 컨텍스트는 하나의 렉시컬 환경을 가지며 변수, 함수의 선언 및 스코프 체인을 관리한다.
- 식별자와 스코프는 실행 컨텍스트의 렉시켤 환경으로 관리하고 코드 실행 순서는 실행 컨텍스트 스택으로 관리한다.
렉시컬 환경으로 관리하는 것 | 실행 컨텍스트 스택으로 관리하는 것 |
식별자 | 코드 실행 순서 |
스코프 |
🔸 식별자는 변수, 함수, 객체의 이름을 나타내는 값이다. 프로그래밍에서 특정 값을 참조할 때 사용하는 이름으로 식별자를 통해 데이터에 접근한다.
🔸 스코프는 변수, 함수, 객체 등이 접근할 수 있는 범위를 의미한다.
렉시컬 환경 : 실행 컨텍스트를 구성하는 컴포넌트 중 하나로 식별자와 식별자에 바인딩된 값. 그리고 상위 스코프에 대한 참조를 기록하는 자료구조이다.
- 실행 컨텍스트가 생성될 때마다 렉시컬 환경이 생성된다.
- 렉시컬 환경은 코드 실행 시점에서 변수 식별자를 저장하고 이를 참조할 때 사용하는 저장소 역할
렉시컬 환경은 다음 두 가지 구성 요소로 이루어져 있다.
- 환경 레코드(Environment Record)
- 키와 값을 가지는 객체 형태의 스코프(전역, 함수 ,블록 스코프)를 생성하고 스코프에 포함된 식별자를 등록하고 등록된 식별자에 바인딩 된 값을 관리하는 저장소
- 각 식별자를 키로 그에 바인딩된 값을 값으로 저장합니다.
- 자바스크립트는 실행 과정에서 선언문만 먼저 실행하여 환경 레코드에 식별자를 등록하고 초기화는 이후에 이루어진다.
🔸 렉시컬 스코프 : 코드가 정의된 위치에 따라 스코프가 결정되는 자바스크립트의 스코핑 규칙 - 외부 렉시컬 환경에 대한 참조(Outer Lexical Environment Reference)
- 외부 렉시컬 환경에 대한 참조는 상위 스코프를 가리킨다.
- 이때 상위 스코프란 외부 렉시컬 환경, 즉 해당 실행 컨텍스트를 생성한 소스코드를 포함하는 상위 코드의 엑시컬 환경을 의미.
- 외부 렉시컬 환경에 대한 참조를 통해 단방향 링크드 리스트인 스코프 체인을 구현
실행 컨텍스트 스택
- 실행 컨텍스트는 스택 자료구조로 관리된다.
- 실행 컨텍스트 스택의 최상위에 존재하는 실행 컨텍스트는 언제나 현재 실행 중인 코드의 실행 컨텍스트다.
스코프 scope(유효범위)
식별자(변수 이름, 함수 이름, 클래스 이름 등)를 참조할 수 있는 유효한 범위
- 스코프는 변수와 함수에 깊은 관련이 있다
- 식별자를 검색할 때 사용하는 규칙이다
- 식별자 결정(identifier resolution) : 이름이 같은 변수 중에서 어떤 변수를 참조해야 할 지를 결정하는 것
- 스코프는 실행 컨택스트와 깊은 관련이 있다.
- 스코프 내에서 식별자의 변수 이름은 중복될 수 없지만(유일) 다른 스코프에서는 같은 변수이름의 식별자가 사용 가능하다. → 스코프는 네임스페이스다.
스코프의 종류
- 변수는 자신이 선언된 위치에 의해 자신의 스코프(유효한 범위)가 정해진다
구분 설명 스코프 변수
전역 | 코드의 가장 바깥 영역 | 전역 스코프 | 전역 변수 |
지역 | 함수 몸체 내부 | 지역 스코프 | 지역 변수 |
스코프 체인
스코프가 계층적으로 연결된 것
- 중첩 함수(nested function) : 함수 몸체 내부에서 정의한 함수
- 외부 함수(outer function) : 중첩 함수를 포함하는 함수
함수의 중첩에 따라 스코프도 중첩이 된다.
⇒ 즉 스코프가 함수의 중첩에 의해 계층적 구조를 가진다.
스코프 페인을 통해 참조할 변수를 검색하는(식별자 결정) 방향은 변수를 참조하는 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색한다.
⇒ 따라서 상위 스코프에서 선언한 변수를 하위 스코프에서도 참조할 수 있는 것이다.
- 스코프 체인은 실행 컨텍스트의 렉시컬 환경을 단방향으로 연결한 것이다.
📌 렉시컬 환경(lexical enviroment) 코드가 어디서 실행되며 주변에 어떤 코드가 있는지 코드의 문맥으로 렉시컬 환경이 이루어 진다.
- 스코프 체인으로 연결된 스코프의 계층적 구조는 부자 관계로 이뤄진 상속(ineritace)와 유사하다.
- ⇒ 상속을 통해 부모의 자산을 자식이 자유롭게 사용 가능 but, 부모는 자식의 자산을 사용하지 못함.
함수 레벨 스코프
- 블록 레벨 스코프(block level scope)
- : 모든 코드 블록(if, for, while …)이 지역 스코프를 생성한다.
- 함수 레벨 스코프(function level scope)ex) var 키워드로 선언된 변수
- : 함수에 의해서만 지역 스코프가 생성한다.
- 동적 스코프(dynamic scope)
- 함수를 어디서 호출 했는지에 따라 함수의 상위 스코프를 결정한다.
- 함수가 호출되는 시점에 동적으로 상위 스코프를 결정한다.
- 렉시컬 스코프(lexical scope), 정적 스코프(static scope)
- 함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정한다.
- 함수 정의가 평가되는 시점에 상위 스코프가 정적으로 결정된다.
렉시컬 스코프
자바스크립트는 렉시컬 스코프를 따른다.
- 함수의 상위 스코프는 함수 정의(함수 선언문, 함수 표현식)가 실행될 때 정적으로 결정된다.
- 함수 선언문으로 함수를 정의하면 런타임 이전에 함수 객체가 먼저 생성된다.
- 함수 객체는 결정된 상위 스코프를 기억한다.
- 함수가 호출될 때마다 상위 스코프를 참조한다.
- 렉시컬 스코프는 클로저와 깊은 관계가 있다.
변수의 실행 시점과 변수 호이스팅
자바스크립트의 모든 선언문은 런타임 이전 단계에서 실행된다.
자바스크립트 엔진은 1. 소스코드의 평가 2. 소스코드의 실행 과정을 나누어서 처리한다.
- 소스코드의 평가 (선언문)
- 실행 컨텍스트를 생성
- 선언문을 먼저 실행 → 식별자를 키로 실행 컨텍스트가 관리하는 스코프(렉시컬 환경의 환경 레코드)에 등록
- 소스코드의 실행 (선언문을 제외한 문)
- 런타임 시작
- 실행에 필요한 정보(변수나 함수의 참조 등)를 실행 컨텍스트가 관리하는 스코프에서 검색해서 취득
- 값의 변경이나 실행 결과는 다시 실행 컨텍스트에 등록
📌 호이스팅 (hoisting) 식별자(변수, 함수, 클래스 등)를 어느 위치에 선언하든지 식별자 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트의 특징
var 키워드로 선언한 변수의 문제점
- 변수 중복 선언을 허용한다.
- 함수 레벨 스코프만 지원한다.
- 의도치 않게 전역 변수가 중복 선언될 수 있음
- var 변수의 선언은 “선언 단계”와 “초기화 단계”가 동시에 진행된다
- 변수 호이스팅에 의해서 변수 선언문 이전에 참조할 수 있지만 할당문 이전에 참조하면 에러 없이 항상 undefined를 반환한다.
let 키워드
- 같은 스코프 내에서 변수 중복 선언 금지
- 블록 레벨 스코프를 따른다.
- “선언 단계”와 “초기화 단계”가 분리되어 진행된다.
- 런타임 이전에 선언 단계가 먼저 실행되지만 초기화 단계는 변수 선언문에 도달했을 때 진행된다 ⇒ 초기화 단계 이전에 변수 접근 시 참조 에러가 발생한다.(TDZ가 발생)
- ⇒ 변수 호이스팅이 발생하지 않는 것처럼 보인다.
📌 일시적 사각지대(temporal dead zone, TDZ) : 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간
- let, const로 선언한 전역 변수는 전역 객체 window의 프로퍼티가 아니다.
const 키워드
- 상수(재할당이 금지된 변수)를 선언하기 위해서 사용한다.
- 반드시 선언과 동시에 초기화를 해야한다.
- 원시(pass-by-value/ 값에 의한 전달)값을 할당한 경우 값 변경 불가
- 객체(pass-by-reference/ 참조에 의한 전달)를 할당한 경우 값 변경 가능 - 재할당 없이 변경가능하기 때문에
'자스핑' 카테고리의 다른 글
[week 02] 실행 컨텍스트와 스코프, 호이스팅 (1) | 2024.11.07 |
---|---|
[Week02] 스코프, 호이스팅, 실행 컨텍스트 (1) | 2024.11.07 |
[week 02] 실행컨텍스트, 스코프, 호이스팅 (2) | 2024.11.06 |
[Week 01] 일급객체로 자스핑 시작 💛 (0) | 2024.10.30 |
[Week 01] Symbol.. 그는.. (0) | 2024.10.30 |