W3docs

JavaScript globalThis und das globale Objekt

Das JavaScript-Objekt globalThis verstehen: globalThis vs. window vs. global, was darauf liegt, warum var und Funktionen dorthin gelangen und wie man den globalen Namespace sauber hält.

Jedes JavaScript-Programm läuft innerhalb eines übergeordneten Objekts, das vor dem eigenen Code bereits existiert: des globalen Objekts. Es enthält die eingebauten Sprachelemente (Array, Math, JSON, setTimeout usw.) und ist der implizite Speicherort für alles, was in einem klassischen Skript auf der obersten Ebene deklariert wird. Diese Seite erklärt, was das globale Objekt ist, wie man es portabel über globalThis erreicht, was tatsächlich darauf liegt, warum manche Deklarationen auf oberster Ebene darauf „auslaufen" und andere nicht, und wie man eigene Globals unter Kontrolle hält.

Was das globale Objekt ist

Das globale Objekt ist die Wurzel der Scope-Kette. Wenn ein Name in keinem umgebenden Funktions- oder Block-Scope gefunden wird, sucht die Engine ihn schließlich als Eigenschaft des globalen Objekts. Deshalb funktionieren Math.max oder JSON.parse überall — sie sind Eigenschaften des globalen Objekts, die die Laufzeitumgebung für einen bereitstellt.

Jede Laufzeitumgebung macht dieses Objekt unter einem anderen Namen zugänglich, was umgebungsübergreifenden Code früher umständlich machte:

  • Browser nennen es window (und stellen auch self sowie frames bereit).
  • Web Workers nennen es self (in einem Worker gibt es kein window).
  • Node.js nennt es global.

globalThis: der portable Zugang zum globalen Objekt

Da der Name je nach Umgebung unterschiedlich ist, wurde mit ES2020 globalThis eingeführt — eine einheitliche Standardreferenz, die überall auf das globale Objekt zeigt: in Browsern, Workers, Node.js, Deno und darüber hinaus. Verwende globalThis, wenn du das echte globale Objekt in Code benötigst, der in mehr als einer Umgebung laufen muss.

console.log(typeof globalThis); // "object" in every environment

// Each of these is true only in its own environment:
// globalThis === window  -> true in a browser tab
// globalThis === self    -> true in a browser or a Web Worker
// globalThis === global  -> true in Node.js

Der Versuch, den falschen Namen zu verwenden, wirft einen ReferenceError — genau das Problem, das globalThis löst:

javascript— editable

Für ein umfassenderes Bild davon, was eine Host-Umgebung zur Sprache hinzufügt, lies die Browserumgebung und Spezifikationen.

Was auf dem globalen Objekt liegt

Das globale Objekt enthält zwei Arten von Dingen:

  1. Eingebaute Sprachelemente, die durch die ECMAScript-Spezifikation definiert und überall vorhanden sind: Object, Array, Function, String, Number, Boolean, Symbol, BigInt, Math, JSON, Date, RegExp, Promise, Map, Set, die Fehlerkonstruktoren sowie globale Funktionen wie parseInt, isNaN und eval.
  2. Host-APIs (Umgebungs-APIs), die von der Laufzeitumgebung hinzugefügt werden: document, fetch, localStorage, setTimeout und alert im Browser; process, Buffer und require in Node.js.
// Built-ins are reachable through the global object:
console.log(globalThis.Math.max(2, 7, 4)); // 7
console.log(globalThis.JSON.stringify({ ok: true })); // {"ok":true}

Warum var und Funktionen auf oberster Ebene darauf gelangen

In einem klassischen (nicht-modularen) Browser-Skript werden eine auf oberster Ebene deklarierte var-Variable und eine Funktionsdeklaration auf oberster Ebene beide zu Eigenschaften von window. Dies ist ein Verhalten aus der Vergangenheit, das aus Kompatibilitätsgründen in der Sprache verankert ist:

// In a classic browser script (not a module):
var greeting = 'hi';
function greet() { return greeting; }

console.log(window.greeting);     // "hi"
console.log(typeof window.greet); // "function"

Block-scoped-Deklarationen verhalten sich anders. let, const und class auf oberster Ebene erzeugen globale Bindungen, hängen sich aber nicht an das globale Objekt:

let count = 1;
const name = 'app';

console.log(window.count); // undefined
console.log(window.name);  // "" — note: window.name is a pre-existing browser property, not your variable

Zwei wichtige Einschränkungen:

  • ES-Module laufen überhaupt nicht aus. Deklarationen von var und function auf oberster Ebene innerhalb eines <script type="module"> (oder einer beliebigen import/export-Datei) haben Modul-Scope, sodass nichts — nicht einmal var — an das globale Objekt gebunden wird.
  • Node.js-Dateien sind ebenfalls Module. Ein var auf oberster Ebene in einer Node-.js-Datei ist auf dieses Modul beschränkt und wird daher nicht an global gebunden wie es in einem klassischen Browser-Skript der Fall wäre.

Dieser Unterschied ist einer der praktischen Gründe, warum moderner Code let/const und Module bevorzugt. Die vollständige Geschichte zu Hoisting und Scoping bei var findest du in das alte "var" und Variablen-Scope und Closures.

Globale Namespace-Verschmutzung vermeiden

Globale Variablen sind gemeinsam genutzter, veränderbarer Zustand: Jedes Skript kann sie überschreiben, und Namenskollisionen verursachen Fehler, die schwer nachzuverfolgen sind. Ein paar Gewohnheiten halten den Namespace sauber:

  • let/const und Module bevorzugen. Sie halten Deklarationen vollständig außerhalb des globalen Objekts.
  • Einen einzigen Namespace verwenden, wenn man wirklich eine globale Variable benötigt, um eine Eigenschaft statt vieler hinzuzufügen.
  • Strict-Mode aktivieren. "use strict" lässt eine nicht deklarierte Zuweisung wie x = 5 einen Fehler werfen, anstatt stillschweigend eine globale Variable zu erzeugen.
javascript— editable

ES-Module halten den globalen Namespace sauber

ES-Module teilen Code in wiederverwendbare Dateien auf, deren Deklarationen auf oberster Ebene privat für jede Datei bleiben, sofern sie nicht explizit exportiert werden. Dies ist die moderne Alternative zum Anhängen von Dingen an das globale Objekt:

// file: math.js
export const add = (a, b) => a + b;

// file: app.js
import { add } from './math.js';
console.log(add(2, 3)); // 5
// `add` is imported, not read from a global — nothing leaks onto window/global.

Fazit

Das globale Objekt ist der Wurzel-Scope der Laufzeitumgebung: Es enthält die eingebauten Sprachelemente und Host-APIs, und in klassischen Skripten sammelt es auch var- und function-Deklarationen auf oberster Ebene. Verwende globalThis, um portabel darauf zuzugreifen, setze auf let/const und Module, um es nicht zu verschmutzen, und aktiviere den Strict-Mode, um versehentliche Globals frühzeitig zu erkennen.

Übungen

Übung
Welche der folgenden Aussagen sind bewährte Vorgehensweisen beim Umgang mit dem globalen Objekt in JavaScript?
Welche der folgenden Aussagen sind bewährte Vorgehensweisen beim Umgang mit dem globalen Objekt in JavaScript?
Was this page helpful?