Topics

Jump to a topic.

Search questions

Find a question by title, tag, or summary.

What is the global object, and how does globalThis relate to global variables?

Questions in this chapter (9)
  • Draft
  • medium
  • Askedsometimes
  • Verified October 2026

Answer

The global object is an ordinary object created per realm that supplies the global scope with its built-in bindings (Array, Math, undefined, …) and any properties added later. globalThis is a property of it that points back to the global this value. Hosts used to name it differently (window and self in browsers, global in Node); globalThis works in all of them.

Which top-level declarations end up on it depends on the declaration and the kind of code. The spec's Global Environment Record has two halves: an Object record backed by the global object, and a Declarative record.

Declaration In a classic script In a module
var, function declaration Global object property (non-configurable) Module scope only
let, const, class Declarative record: a global binding, no property Module scope only
Assignment to an undeclared name (sloppy) Creates a configurable property ReferenceError (strict)

A script's var and function names live in the Object half, so globalThis.name and bare name are the same binding. let/const/class live in the Declarative half, which is searched first, so they can shadow a global property (but not a non-configurable one: let undefined is a SyntaxError). Two scripts that both declare the same top-level let collide with a SyntaxError, because the Declarative record is shared across all scripts in the realm.

Module code has its own Module Environment Record under the global one, so it sees globals but declares nothing in them. Node's CommonJS files are wrapped in a function, so var there isn't global either.

Use globalThis for feature detection (typeof globalThis.fetch) and polyfills. Avoid creating globals; they're shared mutable state.

Example

import vm from 'node:vm';

// node:vm evaluates source as a classic script in a fresh global environment.
const context = vm.createContext({});
vm.runInContext(
  'var fromVar = 1; function fromFn() {} let fromLet = 2; const fromConst = 3; implicit = 4;',
  context,
);

console.log(Object.keys(context).sort()); // → [ 'fromFn', 'fromVar', 'implicit' ]
console.log(vm.runInContext('fromLet + fromConst', context)); // → 5 (global bindings, no properties)

var inModule = 1; // this file is a module, so this is module-scoped
console.log('inModule' in globalThis); // → false

Pitfalls

  • Expecting var x to create globalThis.x in modules, bundles, or Node files. Only a classic <script> (or the REPL-like script context above) does.
  • Saying let and const aren't global. They are global bindings; they are just not properties of the global object.
  • Reading top-level this as the global object. It is undefined in modules and module.exports in a Node CommonJS file; only a classic script's top level has this === globalThis.
  • Treating window as the global object in a browser. globalThis there is a WindowProxy that wraps the real global, so identity checks across frames can surprise you.

Follow-ups

Why was globalThis added?
There was no portable way to reach the global object. window fails in workers and Node, global fails in browsers, and this at the top of a function is undefined in strict mode. globalThis is the same everywhere.
Can globalThis differ from the global object?
In principle, yes; hosts may supply any object as the global this. In browsers it is the WindowProxy. In Node it is the same object as global.
Is it safe to delete a global?
Only properties created as configurable. Script var and function declarations are non-configurable, so delete fails; implicit globals made by sloppy assignment are configurable and can be deleted.

Exercises

Script or module?

var a = 1;
let b = 2;
console.log(globalThis.a, globalThis.b);

What is `this`?

function strictThis() {
  return this;
}
const sloppyThis = new Function('return this'); // Function bodies are sloppy mode
console.log(strictThis(), sloppyThis() === globalThis);