HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
💻
프로그래밍
/
스코프와 실행컨텍스트
스코프와 실행컨텍스트
스코프와 실행컨텍스트

스코프와 실행컨텍스트

태그
실행컨텍스트
스코프
대주제
학습포스팅
상태
완료
수정필요 부분
중분류
Javascript
생성일
Mar 21, 2022 11:07 AM
1. 실행컨텍스트란?1.1 정의1.2 생성시점2. 실행컨텍스트 구성요소2.1 VariableEnvironment2.2 LexicalEnvironment2.3 This3. EnvironmentRecord와 호이스팅3.1 호이스팅 이란3.2 사례를 통해 호이스팅 이해/점검하기4. Scope와 스코프체인, OuterEnvironmentReference4.1 스코프, 스코프체인 이란4.2 OuterEnvironmentReference4.3 사례를 통해 이해/점검하기** This와 Closer는 별도의 포스팅으로참고

1. 실행컨텍스트란?

1.1 정의

  • 실행컨텍스트는 “실행할 코드에 제공할 환경정보들을 모아놓은 객체" 이다.
  • 실행컨텍스트는 생성 시 “콜스택”에 쌓아올려지고, 가장 위의 컨텍스트와 관련 있는 코드들을 실행하는 방식으로 “전체코드의 환경과 순서를 보장”한다.

1.2 생성시점

  • 실행컨텍스트는 4가지 방법을 통해 생성될 수 있다.
    • 전역컨텍스트 는 자동으로 생성된다.
    • 함수 실행 시
    • eval() 함수 실행 시
    • ES6+의 block 생성 시 ()
  • 실행컨텍스트가 생성(활성화) 되는 시점에서 발생하는 일
    • 선언된 변수들을 끌어 올린다. 호이스팅
    • 외부 환경 정보 구성 (LexicalEnviroment의 OuterEnvironmentReference)
    • this의 값을 설정

2. 실행컨텍스트 구성요소

⭐
실행컨텍스트 구성요소 VariableEnvironment : environmentRecord + outerEnvironment (스냅샷) LexicalEnvironment : environmentRecord + outerEnvironment ThisBinding

2.1 VariableEnvironment

  • 실행컨텍스트 생성 시 가장 먼저 생성됨
    • EnvironmentRecord + OuterEnvironmentReference
  • 생성 이후, 그대로 복사하여 LexicalEnvironment 를 생성
  • 최초 실행 시의 정보만을 가지고, 이후에 변화된 정보를 담아내지 못함 스냅샷
    • *실제 JS엔진에서는 VariableEnvironment보다 LexicalEnvironment를 주로 활용함

2.2 LexicalEnvironment

🔑
현재 컨텍스트의 내부 식별자 정보 (EnvironmentRecord)와 외부 컨텍스트의 정보 (OuterEnvironmentReference)를 가지고 있음
  • 첫 생성 시는 VariableEnvironment와 같음
    • EnvironmentRecord + OuterEnvironmentReference
  • 변경사항이 실시간으로 즉각 반영됨
  • EnviromentRecord로 인하여 호이스팅이 발생한다.
  • OuterEnvironmentReference로 인하여 스코프와 스코프체인이 형성된다.

2.3 This

  • 별도 포스팅

3. EnvironmentRecord와 호이스팅

3.1 호이스팅 이란

  • EnvironmentRecord에는 현재 컨텍스트와 관련된 코드의 “식별자 정보”들이 저장된다.
    • 함수의 매개변수 식별자(arguments)
    • 함수 선언 시, 함수 그 자체
    • 변수의 식별자 (var, let, const)
  • EnvironmentRecord가 생성이 완료되는 시점은, 실제 코드가 실행되기 이전이다.
    • 코드가 실행 하기 전, “js엔진은 식별자들을 최상단으로 끌어올려 놓은 다음 실제 코드를 실행”하게 됨
    • 이를 가상의 개념인 호이스팅이라고 지칭함
      • 실제로 끌어올리지는 않지만, 그런 것 같이 동작하므로, 끌어올린 것으로 간주하는 것

3.2 사례를 통해 호이스팅 이해/점검하기

  • [1번 예제]
답안 및 풀이
  • (1): 1 (2): 1 (3) 2
    • 매개 변수는 호이스팅 이전, 최상단에서 선언/할당하는 것과 같이 동작한다.
    • 호이스팅 이후, 코드 동작

4. Scope와 스코프체인, OuterEnvironmentReference

4.1 스코프, 스코프체인 이란

  • 스코프는 “식별자에 대한 유효범위”
  • 스코프체인이란 ”식별자에 대한 유효범위(스코프)를 안에서 부터 바깥으로 차례대로 검색해나가는 것”
  • 스코프체인을 가능하게 하는 것은 LexicalEnvironment의 OuterEnviromentReference 이다.

4.2 OuterEnvironmentReference

  • OuterEnvironmentReference는 현재 호출된 함수가 “선언된 순간”의 LexicalEnvironment를 참조한다.
    • 선언하다 라는 행위가 실제로 일어날 수 있는 시점은 콜 스택 상에서 어떤 실행 컨텍스트가 활성화된 상태일 때뿐이다. 모든 코드는 실행 컨텍스트가 활성화 상태일 때 실행되기 때문이다.
    • 선언된 순간의 LexicalEnvironment는 현재 호출된 함수를 기준으로 바로 위의 컨텍스트의 LexicalEnvironment를 의미한다.
  • 내부 함수에서는 외부함수의 스코프에 접근할 수 있으나, 외부함수에서는 내부 함수의 스코프에 접근할 수 없다.
  • 여러 스코프에서 동일한 식별자를 선언할 경우, 무조건 해당 scope chain에서 가장 먼저 발견된 식별자에만 접근할 수 있게 된다.
    • 전역에도 a 식별자가 존재하지만, inner함수에서는 inner 컨텍스트의 식별자 a에만 접근가능하다.

4.3 사례를 통해 이해/점검하기

  • 예제
  • (0) 전역 컨텍스트 생성
    • 호이스팅을 통해 environmentRecord에 { a, outer } 식별자 정보를 저장
  • (1) ⇒ (2) outer 컨텍스트 생성
    • outer함수가 호출 (1)
    • outer 컨텍스트의 environmentRecord에 { inner } 식별자 정보가 저장
    • outer 컨텍스트의 outerEnvironmentReference에 outer함수 선언된 순간의 컨텍스트인 전역컨텍스트의 LexicalEnvironment인 [전역, { a , outer }] 가 저장된다.
      • outer컨텍스트의 outerEnvironmentReference = [전역컨텍스트, { a, outer }]
  • (3) ⇒ (4) inner 컨텍스트 생성
    • inner 함수가 호출 (3)
    • inner 컨텍스트의 environmentRecord에 { a } 식별자 정보가 저장
    • inner 컨텍스트의 outerEnvironmentReference = [ outer, { inner } ] 정보가 저장
  • (5) console.log(a)
    • 현재 컨텍스트인 inner 컨텍스트의 envirionmentRecord에서 a를 찾아 반환하게 됨
      • 할당된 값이 없으므로 “undefined 출력”
  • (6) var a = 3
    • inner 스코프에 존재하는 변수 a에 3을 할당
    • inner 컨텍스트가 종료 되고, 다시 outer컨텍스트의 코드가 마저 실행 됨
  • (7) console.log(a)
    • outer 컨텍스트의 environmentRecord에서 a를 탐색 ⇒ 없음
    • outer 컨텍스트의 outerEnvironmentReference의 environmentRecord 에서 a 탐색 ⇒ 전역스코프의 a 반환
    • 전역 스코프의 a의 할당 값인 1이 반환
    • outer컨텍스트 종료
  • (8) console.log(a)
    • 전역 컨텍스트의 environmentRecord에서 a를 탐색 ⇒ 발견 후 할당된 값인 1을 반환
 

** This와 Closer는 별도의 포스팅으로

⇒ Go This
⇒ Go Closer

참고

  • 코어자바스크립트
  • 황준일 블로그
 
 
function a(x){ console.log(x); // (1) var x; console.log(x); // (2) var x = 2; console.log(x) // (3) } a(1)
function a(x){ var x = 1; ... } a(1)
function a(x){ var x var x var x x = 1; console.log(x) // (1) 1 console.log(x) // (2) 1 x = 2; console.log(x) // (3) 2 } a(1)
var a = 1; // (0) 전역 컨텍스트 var outer = function (){ // (2) var inner = function (){ // (4) console.log(a); // (5) var a = 3; // (6) } inner(); // (3) inner가 실행될 때, outer의 LexicalEnvironment를 inner컨텍스트의 outerEnvironmentReference로 참조하게 된다. console.log(a); // (7) } outer(); // (1) console.log(a); // (8)