Global object

Every JavaScript environment hands you a bag of ready-made tools: Array, Math, setTimeout, alert, and dozens more. You never declared them, yet they work anywhere in your code. That’s because they live as properties on one special object — the global object — and the engine looks there when a name isn’t found locally.

Some of those tools come from the language itself (Array, Object, parseInt). Others are supplied by the host environment: a browser adds document and location, Node.js adds process and require. The global object is where both worlds meet.

One object, many names

The global object exists everywhere, but its name changes with the environment.

Browser
window
Node.js
global
Any environment
globalThis
The same role, a different name per environment. globalThis works in all of them.

In a browser it’s window. In Node.js it’s global. Other runtimes may pick yet another name. That fragmentation used to make portable code awkward: you couldn’t write one line that reliably reached the global object everywhere.

globalThis fixed that. It’s a standardized name for the global object, guaranteed to point at the same thing no matter where your code runs. Every major browser and current Node.js version supports it.

Since this page runs in a browser, window and globalThis are literally the same object here. The demo below confirms that, then peeks at a handful of built-ins that live on it. Open Edit code and add a name of your own to the names list to see whether the environment provides it.

interactivewindow and globalThis are one object

Properties are directly accessible

Because global functions and variables are properties of the global object, you can reach them with or without the prefix. These two lines do the same thing:

alert("Hello");
// is the same as
window.alert("Hello");

The short form works because when the engine can’t find alert as a local variable, it eventually checks the global object and finds window.alert there. Writing the window. prefix is rarely necessary, but it makes the source of a name explicit — useful when a local variable might otherwise shadow a global one (more on that below).

var leaks onto the global object, let and const don’t

Here’s a quirk worth understanding precisely. In a browser, a global function declaration or a global variable declared with var becomes a property of the global object:

var gVar = 5;

alert(window.gVar); // 5 (became a property of the global object)

Function declarations behave the same way — the function keyword used as a statement in the main code flow, not a function expression assigned to a variable:

function sayHi() {
  alert("Hi");
}

alert(window.sayHi); // function sayHi() { ... }

Now the same code with let instead of var. The property never appears:

let gLet = 5;

alert(window.gLet); // undefined (does NOT become a property of the global object)
window (global object)
gVar: 5
sayHi: function
gLet is nowhere here
separate lexical scope
gLet: 5
At the top level in a browser: var attaches to the global object, let/const do not.

You don’t have to take this on faith — the demo runs the exact scenario in a live browser page. A top-level var shows up as a property of window, while the let binding stays off it. Try switching the var to let in the editor and re-running to watch the first value disappear too.

interactivevar attaches to window, let does not

Putting values on the global object deliberately

Sometimes a value genuinely needs to be reachable from anywhere — for example, information about the signed-in user that every part of the page cares about. When that’s the case, write it as an explicit property of the global object rather than relying on any var side effect:

// make current user information global, to let all scripts access it
window.currentUser = {
  name: "Maya"
};

// somewhere else in code
alert(currentUser.name);  // Maya

// or, if we have a local variable with the name "currentUser"
// get it from window explicitly (safe!)
alert(window.currentUser.name); // Maya

The last line shows why the prefix earns its keep. If some function nearby declares its own local currentUser, the bare name would resolve to that local one. Writing window.currentUser bypasses the local scope and always reads the global property.

Using it for feature detection and polyfills

Because the global object lists what the environment provides, you can probe it to check whether a modern feature exists. For instance, Promise is missing in some ancient browsers:

if (!window.Promise) {
  alert("Your browser is really old!");
}

If a feature is absent, you can supply a polyfill — your own implementation of the standard behavior, installed as a global so the rest of your code can use it as if the environment had it all along:

if (!window.Promise) {
  window.Promise = ... // custom implementation of the modern language feature
}

Type a feature name below and the demo probes it two ways: reading it as a property of globalThis (always safe, yields undefined when absent) versus touching the bare name (which throws a ReferenceError for anything undeclared). Try a real feature like Promise or fetch, then an invented one like timeMachine.

interactiveSafe feature detection vs. a bare reference

Summary

  • The global object holds values that should be available everywhere. That includes language built-ins like Array and Math, plus environment-specific values such as window.innerHeight, the browser window’s height in pixels.
  • It has a universal, portable name: globalThis. More often you’ll see the older environment-specific names — window in the browser, global in Node.js.
  • Store your own values on the global object only when they’re truly global to the whole project, and keep that list short.
  • In the browser, outside of modules, top-level var declarations and function declarations become properties of the global object. let and const do not. Don’t build on this — it’s a compatibility relic.
  • When you do read a global property, window.x (or globalThis.x) is the clearest, most future-proof way to write it.