Notice
Recent Posts
Recent Comments
Link
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

mimizae 님의 블로그

실행 컨텍스트 보충 (전역 객체와 전역 코드 평가) 본문

JS

실행 컨텍스트 보충 (전역 객체와 전역 코드 평가)

mimizae 2025. 11. 9. 16:29

실행 컨텍스트 공부 중 식별자 검색 과정을 공부하며 전역 객체와 전역 코드 평가 과정의 이해가 부족한 듯하여 보충합니다...!!!!!

 

 

전역 객체

전역 객체는 js 엔진에 의해서 어떤 객체보다도 먼저 생성되어서 어떤 객체에도 속하지 않는 최상위 객체가 됨.

 

근데 이 객체가 표준 빌트인 객체(누구나 가지고 있는), 환경에 따른 호스트 객체(node.js인지 뭔지에 따라), 그리고 var 키워드로 선언한 전역 변수와 함수 선언문으로 선언된 전역 함수를 프로퍼티로 갖는다.

 

여기에서 표준 빌트인 객체란...

Object, Array, Function, Math, Date, JSON, RegExp, Promise, Error, ... 등등

아래와 같은 것!

const arr = new Array(); // 표준 빌트인 객체 Array
const now = new Date();  // 표준 빌트인 객체 Date
const n = Math.random(); // 표준 빌트인 객체 Math

 

호스트 객체란...

자바스크립트를 실행하는 환경(host environment) 이 추가로 제공하는 객체이다.

즉, ECMAScript 명세에는 없지만, “브라우저라서 필요한 기능” 또는 “Node.js라서 필요한 기능”을 제공한다.

 

예를 들어,

  • 브라우저에서는 DOM 조작을 위해 document, window, fetch, alert 같은 게 필요하고
  • Node.js에서는 파일 시스템이나 서버 관련 기능을 위해 fs, process, require 같은 게 필요하다
 
// 브라우저에서
console.log(window.location.href);

// Node.js에서
console.log(process.version);

 

환경에 따라 다르기 때문에, 브라우저에 있는 window나 document는 Node.js에 없고, Node.js에 있는 require나 process는 브라우저에 없다.

 

 

(표준 빌트인 객체랑, 환경에 따른 호스트 객체를 먼저 프로퍼티로 가지고 있는 건 이해가 되는데, 전역 변수와 함수까지? 흠... 🤔 이건 전역 코드 평가 과정을 알아보면 깨달을 수 있을 것이다.)

 


전역 코드 평가

전역 코드가 평가된다면

전역 실행 컨텍스트가 생성이 되고 이 전역 실행 컨텍스트에 전역 렉시컬 환경이 바인딩 된다.

 

이 전역 렉시컬 환경은 전역 환경 레코드외부 렉시컬 환경에 대한 참조로 구성되는데,

전역 환경 레코드는 전역 변수와 전역 함수를 관리하고, 전역 객체에 이미 존재하는 빌트인 전역 프로퍼티, 빌트인 전역 함수, 표준 빌트인 객체전역 스코프에서 접근할 수 있도록 제공한다.

 

(엥? 전역 객체의 어쩌고저쩌고를 왜 제공하지? 🤔)

 

전역 환경 레코드는 객체 환경 레코드, 선언적 환경 레코드로 구성되어있다.

 

객체 환경 레코드는 전역 객체과 관리하던 var 키워드로 선언한 전역 변수, 함수 선언문으로 정의한 전역 함수, 빌트인 전역 프로퍼티와 빌트인 전역 함수, 표준 빌트인 객체를 관리하고

선언적 환경 레코드는 let, const 키워드로 선언한 전역 변수를 관리한다. 

 

객체 환경 레코드는 BindingObject라고 부르는 전역 객체와 연결된다.

 

이때! 전역 코드 평가 과정에서 var 키워드로 선언한 전역 변수와 함수 선언문으로 정의된 전역 함수는 객체 환경 레코드에 연결된 BindingObject를 통해 전역 객체의 프로퍼티와 메서드가 된다.

 

 

아하, 그래서!!


전역 객체가 표준 빌트인 객체(누구나 가지고 있는), 환경에 따른 호스트 객체(node.js인지 뭔지에 따라), 그리고 var 키워드로 선언한 전역 변수와 함수 선언문으로 선언된 전역 함수를 프로퍼티를 갖는다는 것에서

 

왜 전역 환경 레코드가 아니라 전역 객체가 전역 변수와 함수 프로퍼티를 가지고 있는 건지?

 

또 갑자기 전역 환경 레코드는 전역 변수와 전역 함수를 관리하고, 전역 객체에 이미 존재하는 빌트인 전역 프로퍼티, 빌트인 전역 함수, 표준 빌트인 객체전역 스코프에서 접근할 수 있도록 제공한다는 건지 이해가 안 되었는데...

 

코드가 실행 되기 전, JS 엔진에 의해 전역 객체가 생성될 때 표준 빌트인 객체, 환경에 따른 호스트 객체가 부여되고

전역 코드 평가 단계에서!!! 전역 실행 컨텍스트가 생성되며 전역 환경 레코드의 객체 환경 레코드에 전역 객체인 BindingObject가 바인딩 되기 때문에!! (참조를 가지기 때문에)

 

전역 환경 레코드는 전역 변수와 전역 함수를 관리하고, 전역 객체에 이미 존재하는 빌트인 전역 프로퍼티, 빌트인 전역 함수, 표준 빌트인 객체전역 스코프에서 접근할 수 있도록 제공하고,

 

객체 환경 레코드의 BindingObject를 통해 var 키워드로 선언한 전역 변수, 함수 선언문으로 선언된 전역 함수가 전역 객체의 프로퍼티와 메서드로 등록 되었기 때문에 전역 객체가 전역 변수와 함수 프로퍼티를 가지고 있는 것이다...!!!!!!!!!!!!

 

++ 그래서 var a = 1; 하면 실제로는 window.a = 1; 과 같아지는 것이다 (브라우저 기준).

 

좀 더 깔끔히 정리를 해 보자면,

 

전역 객체는 코드 실행 전(엔진 초기화 단계)에서 표준 빌트인 객체와 호스트 객체를 포함하여 생성된다.
이후 전역 코드 평가 단계에서 전역 실행 컨텍스트가 생성되고, 전역 렉시컬 환경의 전역 환경 레코드가 전역 객체를 바인딩 객체(BindingObject)로 참조한다.

이때 var 변수와 함수 선언문은 객체 환경 레코드를 통해 전역 객체의 프로퍼티로 등록된다. 그래서 결과적으로 그 셋을 모두 프로퍼로 가지는 것이다.

 

이때 전역 객체의 함수 프로퍼티의 값(value)은, 함수 선언문으로 만들어진 함수 객체참조(reference)이다.

즉, window.foo → foo 함수 객체를 참조!!

 

 

 

 


This 바인딩

(전역 코드 평가 과정에 대해 살펴 보다 this 바인딩 부분이 나와서 짧게 정리하고자 한다. this 바인딩에 대해서는 추후 더 길게... 깊이 다룰 예정이다.)

 

책의 예제에서 어떤 함수든 평가 과정에서의 this 바인딩이 전역 객체로 향했다. 이유가 뭘까!!

 

결론부터 말하자면,

전역 코드에서 this는 전역 객체를 참조하고 함수 내부의 this는 “어떻게 호출되었느냐(호출 방식)”에 따라 결정된다.
단, 기본 호출 방식에서는 전역 객체를 가리키기 때문에, 모두 전역 객체로 향하는 현상이 일어난 것이다.

 

전역 코드의 this

전역 실행 컨텍스트가 만들어질 때, 전역 렉시컬 환경 안에는 this 바인딩이 있고 이 바인딩은 전역 객체를 가리킨다.

 
console.log(this === window); // true (브라우저) 
console.log(this === global); // true (Node.js)

 

함수의 this

여기서 중요한 점은 this는 렉시컬(정적) 이 아니라 동적(dynamic) 으로 결정된다.

즉, 함수를 어디서 선언했는지(렉시컬 환경) 가 아니라 어떻게 호출했는지(호출 방식) 에 따라 바뀐다!

 
function foo() { 
    console.log('foo this:', this); 

    function bar() { 
        console.log('bar this:', this); 
    } 
    bar(); 
} 

foo();

 

  1. 전역 코드 평가
    • 전역 실행 컨텍스트 생성
    • 전역 렉시컬 환경의 this 바인딩 → 전역 객체
    • foo가 전역 객체(window/global)의 프로퍼티로 등록됨 (window.foo)
  2. 전역 코드 실행 (foo() 호출)
    • foo 호출 → foo 실행 컨텍스트 생성
    • foo의 this 바인딩은 호출 방식에 따라 결정된다.
      • foo()는 그냥 “단독 호출”이므로 → this = 전역 객체 (브라우저에서는 window)
    • bar()도 단독 호출이므로, 동일하게 this = 전역 객체.
 

 

 

만약... 호출 방식이 달라지면?

 

(1) 객체의 메서드로 호출한 경우

const obj = {
  foo: function () {
    console.log(this); // obj
  }
};
obj.foo(); // this = obj
 

→ obj.foo()처럼 점(.)을 통해 호출하면 this는 점 앞의 객체이다!!!!!!

 

(2) 생성자 함수 호출 (new)

function Foo() {
  console.log(this);
}
new Foo(); // this = Foo의 새 인스턴스
 

→ new 키워드로 호출하면 this는 새로 생성된 객체(instance)!!!!!!!

 


모던 자바스크립트 딥 다이브를 공부하고 정리한 글입니다!

'JS' 카테고리의 다른 글

클로저(Closure)란? (1)  (0) 2025.11.11
this에 대해서  (0) 2025.11.11
실행 컨텍스트란?  (0) 2025.11.03
JavaScript의 Scope에 대해서 (3)  (0) 2025.11.03
JavaScript의 Scope에 대해서 (2)  (0) 2025.10.26