The browser environment
Learn how JavaScript meets the browser: window, globalThis, the DOM, browser environment objects, web standards, and the different places scripts can run.
- 01What the browser addsSeparate ECMAScript from host APIs such as
window,document,location, timers, andfetch. - 02How globals behavePredict which top-level declarations become properties on
window, and why modules differ. - 03Where code runsCompare page scripts, module scripts, workers, and Node-style environments without mixing their globals.
Welcome to the browser host
You already know a lot of JavaScript: values, functions, objects, scope, classes, errors, and asynchronous code. Stage 7 opens a new door. The same language now runs inside a host: the browser. The host gives JavaScript objects that are not part of the language itself, but make web pages possible.
Think of this lesson as the map taped beside the browser console. It answers: what is window, why does document exist, what does people mean by “BOM”, which specs define these things, and why a page script, module script, worker, and Node program do not all have the same globals.
The browser environment is ECMAScript running inside a web browser plus the browser-provided APIs around it: the page tree, navigation state, device information, timers, dialogs, network tools, and more.
JavaScript by itself is the engine. It knows how to run functions, compare values, create promises, and build arrays. It cannot steer a page, honk a dialog, or read the address bar until the browser wraps that engine in a car with controls.
- In real life: The engine
- In JavaScript: The JavaScript engine running ECMAScript
- In real life: The wheels and steering
- In JavaScript: The DOM: read and change the page
- In real life: The dashboard
- In JavaScript:
location,history,navigator, andscreen - In real life: The radio and gadgets
- In JavaScript: Timers,
fetch, console tools, and other host APIs
Where the analogy stops: An engine can be moved into different vehicles. JavaScript can run in browsers, workers, Node, and more; each host attaches different controls.
We will link back to Engines, runtimes & hosts and Manuals & specifications instead of repeating them. Today is about the browser-specific surface you are about to use in every DOM lesson.
window as the global object
INTERACTIVEIn a normal page script, the browser exposes a huge object named window. It is both the window-like browser environment and the global object for classic scripts. That is why code can write alert("Hi") instead of window.alert("Hi"): global property lookup finds the property on window.
But there is a sharp edge from the old var lesson: top-level var and top-level function declarations in a classic script create properties on the global object. Top-level let, const, and class create global lexical bindings, but not window properties. The names are still visible to other classic scripts because they share a global lexical scope; they just are not object properties.
Step through one classic-script declaration and watch the difference between a global binding and a global property.
script
function greet() { return "hello from a classic script";}console.log("fruit" in globalThis);console.log(globalThis.fruit);console.log(typeof greet);Now let a real sandboxed frame answer the same question. The code is predefined; the parent validates event.source before trusting the message. Toggle to a module script and notice that module top-level declarations are module-scoped: even var fruit no longer creates window.fruit.
<div id="banner">Named access demo</div><script>var fruit = "mango";let veggie = "carrot";function greet() { return "hi"; }parent.postMessage({ source: "global-explorer", mode: "classic", rows: [ ["'fruit' in window", String("fruit" in window)], ["window.veggie", String(window.veggie)], ["typeof window.greet", typeof window.greet], ["globalThis === window", String(globalThis === window)], ["window.window === window", String(window.window === window)], ["self === window", String(self === window)], ["window.banner exists", String(Boolean(window.banner))] ]}, "*");</script>Waiting for the frame to report.
Waiting for the sandboxed frame…
Browsers expose some elements with IDs as window properties, so <div id="banner"> may appear as window.banner. It is old compatibility behavior. Use document.querySelector("#banner") or document.getElementById("banner") in real code.
Modern code should use globalThis when it truly needs “the global object, wherever I am.” In a page script, globalThis === window is true; precisely, browsers expose a WindowProxy that forwards to the current window. In a worker, globalThis is the worker global scope and is also available as self. In Node, it is Node’s global object.
DOM and BOM: page furniture and browser dashboard
SORT ITwindow as a houseThe global browser house contains many familiar names. The most important for the next lesson is document: a live object representation of the HTML page. You can search it, read nodes from it, and change it. Other objects tell you about the surrounding browser: URL, navigation history, screen, and device hints.
- In real life: The house itself
- In JavaScript:
window, the browser global object - In real life: Furniture you can rearrange
- In JavaScript:
document, the page tree you can read and change - In real life: The address plate
- In JavaScript:
location, the current URL - In real life: Rooms you visited
- In JavaScript:
history, the navigation stack - In real life: The resident’s ID card
- In JavaScript:
navigator, browser and device hints
Where the analogy stops: The page is not literally inside window like furniture in a room. These are separate objects linked by browser standards.
The DOM (Document Object Model) is the standard API for representing documents as nodes and letting scripts read or change them. The next lesson, “The DOM tree,” zooms in on that structure. BOM, short for Browser Object Model, is an informal nickname for browser objects that are not the document tree itself: location, history, navigator, screen, dialogs, and more. Most of what people call BOM is specified in the HTML Standard, not in one official “BOM spec.”
Array.prototype.mapJSON.parsePromisedocument.querySelectorlocation.hrefhistory.backalertsetTimeoutconsole.logfetchprocess.envrequire
Sort each name by the standard or host that provides it. The trick: useful does not always mean ECMAScript.
const snapshot = { pathname: location.pathname, language: navigator.language, online: navigator.onLine, viewport: innerWidth + " × " + innerHeight, screenWidth: screen.width, devicePixelRatio, historyLength: history.length, title: document.title, readyState: document.readyState};These values are read after the page mounts, so the server render never guesses your browser size, language, or history. Resize the window and the viewport row updates.
The specs behind the house
MAPBrowser APIs feel like one big object pile, but they come from several standards that coordinate with each other. This matters because it explains why Array.prototype.map works in Node but document.querySelector does not, and why fetch can appear in more than one host without becoming an ECMAScript feature.
If each browser invented its own house rules, web developers would have to rebuild every site four times. Standards act like building codes: shared instructions so different teams can build compatible houses.
- In real life: Building code for concrete and wiring
- In JavaScript: ECMAScript for core language behavior
- In real life: Rules for rooms, doors, and addresses
- In JavaScript: HTML and DOM standards for pages and navigation
- In real life: Rules for plumbing and utilities
- In JavaScript: Fetch, Console, CSSOM, and related standards
- In real life: Inspectors checking compliance
- In JavaScript: Browser tests and compatibility work
Where the analogy stops: Specs do not force every implementation to be bug-free instantly. Browsers still ship fixes over time, so test behavior when compatibility matters.
| Thing | Mostly specified by | Why you care |
|---|---|---|
let, functions, arrays, promises | ECMAScript | Works across hosts because it is the language core. |
document, elements, nodes, events | DOM Living Standard | This is how scripts see the page as a tree. |
window, location, history, timers, classic script loading | HTML Living Standard | This is most of the browser environment around the document. |
fetch | Fetch Standard | Network requests are a web platform API, not a language keyword. |
console.log | Console standard / host support | Developer logging is provided by the host. |
| CSS rules exposed to scripts | CSSOM | Scripts can inspect and change some style information. |
You do not need to memorize spec names to write a button click handler. You do need the habit: when a name is missing, ask “is this language JavaScript, a browser API, a worker API, or a Node API?” That question saves hours of confusion.
Where scripts run
REAL WORKER“JavaScript runs in the browser” is true but incomplete. A classic page script runs with window and document. A module script also runs in the page and can use browser APIs, but its top-level declarations stay inside the module. A Web Worker runs off the main page thread with self and no document. Node runs outside the browser with process and global, not window.
self.postMessage({ windowType: typeof window, documentType: typeof document, selfType: typeof self, importScriptsType: typeof importScripts, globalThisType: typeof globalThis});…………undefinedundefinedobjectfunctionobjectundefinedundefinedobjectobjectobjectStarting a real Worker from a Blob URL. If that is blocked, the expected static worker column remains shown.
| Place | Global access | Can touch the page? | Typical job |
|---|---|---|---|
| Classic page script | window, self, globalThis | Yes, through document | Small page behavior or older scripts. |
| Module page script | window, self, globalThis | Yes, through document | Modern organized browser code with imports and exports. |
| Web Worker | self, globalThis | No document | CPU work or background coordination without blocking the page. |
| Node | global, globalThis, process | No browser page | Servers, scripts, tooling, and tests. |
Where you will use this
Browser-environment thinking shows up whenever code reaches outside the ECMAScript core. The following snippet is ordinary front-end code: it finds an element through the DOM, reads the URL from the browser environment, asks navigator about connectivity, and listens for browser events.
const status = document.querySelector("#status"); function describePage() { const path = location.pathname; const online = navigator.onLine ? "online" : "offline"; status.textContent = `You are on ${path} and currently ${online}.`;} window.addEventListener("online", describePage);window.addEventListener("offline", describePage);describePage();This is why separating “language” from “host” is practical, not trivia. If this snippet fails in a Node test, document is the first suspect. If status is null, the page element is missing or the script ran before it existed. If navigator.onLine seems too optimistic, remember it is a browser hint, not a guarantee that your server is reachable.
Common misconceptions
DEBUG- “Everything global is on
window.” Top-levellet,const, andclassare global lexical bindings in classic scripts, not window properties. - “Modules cannot use browser APIs.” Browser modules can use
document,location, and friends. Their own top-level declarations are module-scoped. - “BOM is an official twin of DOM.” BOM is informal. The real standards are mostly HTML plus related web platform specs.
- “
fetchandsetTimeoutare ECMAScript.” They are host APIs. ECMAScript defines promises; hosts define many operations that create or schedule them. - “Workers are mini pages.” Workers run JavaScript, but they have no
documentand cannot directly rearrange page nodes. - “Named element access is convenient, so I should use it.” It is legacy and collision-prone. Query the document explicitly.
Practice exercises
4 EXERCISESIn a classic script, what are the two console lines?
var pet = "otter";
let snack = "kelp";
console.log("pet" in globalThis);
console.log(globalThis.snack);The first line prints true because top-level var pet creates globalThis.pet. The second line prints undefined because top-level let snack is not a property on globalThis.
Who provides document.querySelector: ECMAScript, DOM, HTML/BOM, another host API, or Node?
document.querySelector is provided by the DOM. It searches the document tree for matching elements.
The function works in one browser tab but fails after markup changes. Rewrite it so it does not rely on named access.
function updateBanner() {
banner.textContent = "Ready";
}function updateBanner() {
const banner = document.querySelector("#banner");
if (banner) banner.textContent = "Ready";
}Do not rely on legacy named access through window.banner. Query the document explicitly, then handle the case where the element is not present.
This object mimics the report from a worker. Type the three comma-separated words it prints.
const workerGlobal = {
windowType: "undefined",
documentType: "undefined",
selfType: "object"
};
console.log(workerGlobal.windowType + "," + workerGlobal.documentType + "," + workerGlobal.selfType);The program prints undefined,undefined,object: no window, no document, and an object-like self for the worker global scope.
Check your understanding
7 QUESTIONSQuestion 1 of 7What is the browser environment?
Choose an answer to see the explanation.
Question 2 of 7What does this classic script print?
Read the code, then predictvar fruit = "mango"; let veggie = "carrot"; console.log("fruit" in globalThis); console.log(globalThis.veggie);Choose an answer to see the explanation.
Question 3 of 7Which feature is defined by ECMAScript rather than a browser host standard?
Choose an answer to see the explanation.
Question 4 of 7What does
globalThismean in a web page script?Choose an answer to see the explanation.
Question 5 of 7Which statement about modules is correct?
Choose an answer to see the explanation.
Question 6 of 7What is the informal term BOM usually talking about?
Choose an answer to see the explanation.
Question 7 of 7What does this print in Node’s test-like environment?
Read the code, then predictconsole.log(typeof window); console.log(typeof globalThis);Choose an answer to see the explanation.
Key takeaways
- ECMAScript is the language core; the browser host adds web APIs around it.
- In page scripts,
windowis the browser global object andglobalThis === windowis true. - Classic top-level
varand function declarations create window properties;let,const,class, and module top-level declarations do not. - The DOM is the document tree API. BOM is an informal nickname for browser environment objects mostly specified by HTML.
- Workers and Node share JavaScript but not the same globals as a page.
Final definition: the browser environment is JavaScript plus the standards-based objects a browser supplies so code can observe and change a web page.
Up next: The DOM tree.