W3docs

JavaScript globalThis et l'objet global

Découvrez l'objet global JavaScript : globalThis vs window vs global, ce qu'il contient, pourquoi var et les fonctions y fuient, et comment éviter de polluer l'espace de noms global.

Tout programme JavaScript s'exécute à l'intérieur d'un objet de niveau supérieur qui existe avant même que votre code démarre : l'objet global. Il contient les éléments intégrés du langage (Array, Math, JSON, setTimeout, etc.) et constitue le foyer implicite de tout ce que vous déclarez au sommet d'un script classique. Cette page explique ce qu'est l'objet global, comment y accéder de manière portable avec globalThis, ce qui s'y trouve réellement, pourquoi certaines déclarations de niveau supérieur « fuient » vers lui tandis que d'autres non, et comment garder le contrôle de vos propres variables globales.

Ce qu'est l'objet global

L'objet global est la racine de la chaîne de portée. Lorsque vous référencez un nom introuvable dans une fonction ou un bloc englobant, le moteur le recherche finalement en tant que propriété de l'objet global. C'est pourquoi Math.max ou JSON.parse fonctionnent partout — ce sont des propriétés de l'objet global que le runtime configure pour vous.

Chaque runtime expose cet objet sous un nom différent, ce qui rendait historiquement le code multi-environnement maladroit :

  • Les navigateurs l'appellent window (et exposent aussi self, ainsi que frames).
  • Les Web Workers l'appellent self (il n'y a pas de window dans un worker).
  • Node.js l'appelle global.

globalThis : le global portable

Étant donné que le nom varie selon l'environnement, ES2020 a ajouté globalThis — une référence standard unique qui pointe vers l'objet global partout : navigateurs, workers, Node.js, Deno, et plus encore. Utilisez-le chaque fois que vous avez besoin du véritable objet global dans un code qui doit s'exécuter dans plusieurs environnements.

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

Tenter d'utiliser le mauvais nom lève une ReferenceError, ce qui est exactement le problème que globalThis résout :

javascript— editable

Pour avoir une vue d'ensemble de ce qu'un environnement hôte ajoute par-dessus le langage, consultez l'environnement navigateur et les specs.

Ce qui se trouve sur l'objet global

L'objet global contient deux types d'éléments :

  1. Les éléments intégrés du langage, définis par la spécification ECMAScript et présents partout : Object, Array, Function, String, Number, Boolean, Symbol, BigInt, Math, JSON, Date, RegExp, Promise, Map, Set, les constructeurs d'erreurs, et les fonctions globales comme parseInt, isNaN et eval.
  2. Les API hôtes (d'environnement), ajoutées par le runtime : document, fetch, localStorage, setTimeout et alert dans le navigateur ; process, Buffer et require dans 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}

Pourquoi var et les fonctions de niveau supérieur y fuient

Dans un script navigateur classique (non-module), un var déclaré au niveau supérieur et une déclaration de fonction de niveau supérieur deviennent toutes deux des propriétés de window. C'est un comportement hérité ancré dans le langage pour des raisons de rétrocompatibilité :

// 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"

Les déclarations à portée de bloc se comportent différemment. let, const et class au niveau supérieur créent des liaisons globales mais ne s'attachent pas à l'objet global :

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

Deux mises en garde importantes :

  • Les modules ES ne fuient pas du tout. Les déclarations var et function de niveau supérieur à l'intérieur d'un <script type="module"> (ou tout fichier avec import/export) ont une portée de module, donc rien — pas même var — ne s'attache à l'objet global.
  • Les fichiers Node.js sont aussi des modules. Un var de niveau supérieur dans un fichier Node .js est limité à ce module, il ne s'attache donc pas à global comme le ferait un script navigateur classique.

Cette différence est l'une des raisons pratiques pour lesquelles le code moderne préfère let/const et les modules. Pour l'histoire complète du hissage et de la portée derrière var, lisez l'ancien "var" et la portée des variables et les closures.

Éviter la pollution globale

Les variables globales sont un état partagé et mutable : tout script peut les écraser, et les collisions de noms provoquent des bugs difficiles à tracer. Quelques bonnes habitudes permettent de garder l'espace de noms propre :

  • Préférer let/const et les modules. Ils tiennent les déclarations entièrement à l'écart de l'objet global.
  • Utiliser un seul espace de noms lorsque vous avez vraiment besoin d'une variable globale, pour n'ajouter qu'une propriété au lieu de plusieurs.
  • Activer le mode strict. "use strict" fait en sorte qu'une affectation non déclarée comme x = 5 lève une erreur au lieu de créer silencieusement une variable globale.
javascript— editable

Les modules ES gardent l'espace de noms global propre

Les modules ES divisent le code en fichiers réutilisables dont les déclarations de niveau supérieur restent privées à chaque fichier, sauf si elles sont explicitement exportées. C'est l'alternative moderne à l'attachement de choses à l'objet global :

// 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.

Conclusion

L'objet global est la portée racine du runtime : il héberge les éléments intégrés du langage et les API hôtes, et dans les scripts classiques, il collecte également les déclarations var et function de niveau supérieur. Utilisez globalThis pour y accéder de manière portable, appuyez-vous sur let/const et les modules pour éviter de le polluer, et activez le mode strict pour détecter les variables globales accidentelles rapidement.

Pratique

Pratique
Lesquelles des propositions suivantes sont de bonnes pratiques lors de l'utilisation de l'objet global en JavaScript ?
Lesquelles des propositions suivantes sont de bonnes pratiques lors de l'utilisation de l'objet global en JavaScript ?
Was this page helpful?