Skip to content
JavaScript js browser 5 min read

The Window Object

In a browser, window is the global object — the root from which every other browser feature hangs. It represents the tab or frame your script runs in, holds all your global variables and functions, and serves as the entry point to the Browser Object Model (BOM): things like location, history, navigator, and localStorage. Understanding window is understanding the environment your code lives in.

window is the global object

Every global you declare in browser script becomes a property of window. When you read a bare identifier like alert or setTimeout, the engine resolves it against the global object. That is why alert(...) and window.alert(...) are the same call.

function greet() {
  return "hi";
}

console.log(window.greet === greet); // true
console.log("setTimeout" in window); // true
console.log(window.console === console); // true

Output:

true
true
true

There is one important nuance: var declarations and function declarations at the top level become window properties, but let, const, and class do not. They live in a separate lexical scope, so they stay off the global object.

var legacy = 1;
let modern = 2;

console.log(window.legacy); // 1
console.log(window.modern); // undefined

Output:

1
undefined

Avoid attaching things to window on purpose. Global state is hard to track and collides easily across scripts. Prefer modules (import/export), which keep their bindings private.

globalThis: one name everywhere

The catch with window is that it only exists in browsers. In Node.js the global object is global; in a Web Worker it is self. ES2020 introduced globalThis as a single, portable reference to the global object in any environment.

// Works in browsers, Node, workers, Deno — everywhere.
globalThis.appConfig = { debug: true };

console.log(globalThis === window); // true (in a browser tab)
EnvironmentGlobal object nameglobalThis works?
Browser (main thread)window (also self)Yes
Web WorkerselfYes
Node.jsglobalYes
DenoYes

Reach for globalThis whenever you write code that might run outside a browser. Reserve window for code that is genuinely browser-only.

Viewport and scroll properties

window exposes live measurements of the viewport and the current scroll position. These update as the user resizes the tab or scrolls, so reading them always gives the current value.

PropertyDescription
innerWidth / innerHeightViewport size in CSS pixels, including scrollbars.
outerWidth / outerHeightThe whole browser window, including chrome.
scrollX / scrollYHow far the document has scrolled, in pixels.
devicePixelRatioPhysical pixels per CSS pixel (2 on most retina screens).
console.log(`Viewport: ${window.innerWidth} x ${window.innerHeight}`);
console.log(`Scrolled down: ${window.scrollY}px`);

// Programmatic scrolling, with smooth animation:
window.scrollTo({ top: 0, behavior: "smooth" });

The demo below reads these values live. Resize the result pane and scroll it to watch the numbers change.

<!DOCTYPE html>
<html>
<head>
  <style>
    body { font-family: system-ui, sans-serif; margin: 0; padding: 24px; height: 1500px; }
    #panel {
      position: fixed; top: 12px; left: 12px;
      background: #1e293b; color: #e2e8f0;
      padding: 14px 18px; border-radius: 8px;
      font-family: monospace; line-height: 1.6;
    }
  </style>
</head>
<body>
  <div id="panel"></div>
  <p>Scroll and resize this pane to see <code>window</code> update.</p>

  <script>
    const panel = document.querySelector("#panel");

    function render() {
      panel.textContent =
        `innerWidth:  ${window.innerWidth}\n` +
        `innerHeight: ${window.innerHeight}\n` +
        `scrollY:     ${Math.round(window.scrollY)}\n` +
        `dpr:         ${window.devicePixelRatio}`;
    }

    render();
    window.addEventListener("resize", render);
    window.addEventListener("scroll", render);
  </script>
</body>
</html>

Dialog methods: alert, confirm, prompt

window provides three blocking dialogs. They pause script execution until the user responds, which makes them handy for quick demos but unsuitable for production UI — they freeze the whole page and cannot be styled.

MethodReturnsUse
alert(msg)undefinedShow a message with an OK button.
confirm(msg)booleanAsk a yes/no question; true if OK.
prompt(msg, default)string | nullAsk for text input; null if cancelled.
alert("Saved successfully.");

if (confirm("Delete this file?")) {
  console.log("user confirmed");
}

const name = prompt("What is your name?", "Guest");
console.log(name === null ? "cancelled" : `Hello, ${name}`);

Try all three in the interactive example below.

<!DOCTYPE html>
<html>
<head>
  <style>
    body { font-family: system-ui, sans-serif; padding: 24px; }
    button { font-size: 1rem; padding: 8px 14px; margin-right: 8px; cursor: pointer; }
    #out { margin-top: 16px; font-family: monospace; }
  </style>
</head>
<body>
  <button id="a">alert</button>
  <button id="c">confirm</button>
  <button id="p">prompt</button>
  <div id="out">Click a button.</div>

  <script>
    const out = document.querySelector("#out");

    document.querySelector("#a").addEventListener("click", () => {
      alert("This is an alert.");
      out.textContent = "alert() returned undefined";
    });

    document.querySelector("#c").addEventListener("click", () => {
      const ok = confirm("Are you sure?");
      out.textContent = `confirm() returned ${ok}`;
    });

    document.querySelector("#p").addEventListener("click", () => {
      const value = prompt("Type something:", "hello");
      out.textContent = `prompt() returned ${JSON.stringify(value)}`;
    });
  </script>
</body>
</html>

Dialogs are synchronous and modal: nothing else runs while one is open. Browsers also suppress them in some contexts (e.g. during page unload, or repeated dialogs). Build real confirmations with your own DOM-based modals.

Other useful window members

Beyond globals and dialogs, window is the namespace for much of the BOM and several events worth knowing.

// BOM entry points hanging off window:
console.log(window.location.href);   // current URL
console.log(window.navigator.language); // e.g. "en-US"

// The DOMContentLoaded vs load distinction:
window.addEventListener("load", () => {
  console.log("all assets, including images, are ready");
});

// Open and reference other windows/tabs:
const popup = window.open("https://example.com", "_blank");

Best Practices

  • Prefer globalThis over window in code that may run in Node, workers, or other runtimes.
  • Keep globals to a minimum; use ES modules instead of attaching values to window.
  • Remember that let, const, and class do not create window properties — only var and function declarations do.
  • Treat window.innerWidth/scrollY as live reads; cache them in a variable if you reference them many times in a tight loop.
  • Throttle or debounce resize and scroll handlers, which fire very frequently.
  • Use alert/confirm/prompt only for prototypes; they block the thread and cannot be styled — ship custom modals instead.
Last updated June 1, 2026
Was this helpful?