JavaScript Tutorial

Window Object in JavaScript: Complete Guide with Examples

Master the JavaScript Window object — browser dimensions, timers, setTimeout, setInterval, alerts, scrolling, localStorage, open/close tabs, and real-world examples with best practices.

Welcome back! 👋 In the previous lesson, you got an overview of the DOM & BOM section. Now let's dive deep into the foundation of everything in the browser — the window object!

The window object is the global object in every browser environment. Everything you interact with in JavaScript — console, document, Math, Date, alert, setTimeout — they all live inside window. It is the outermost container of everything.

Understanding window deeply makes you far more effective at building real browser-based JavaScript. Let's master it!


What is the Window Object?

The window object represents the browser window (or tab) that contains your web page. It is the global scope — every variable you declare at the top level becomes a property of window.

// These are identical — window is implicit
window.console.log("Hello");
console.log("Hello");

window.alert("Hi!");
alert("Hi!");

var globalVar = "I'm global";
console.log(window.globalVar); // "I'm global"

Window Dimensions

Viewport Size (Inside Browser Chrome)

console.log(window.innerWidth);  // Width of the content area
console.log(window.innerHeight); // Height of the content area

Full Browser Size (Including Toolbars)

console.log(window.outerWidth);  // Full window width including browser UI
console.log(window.outerHeight); // Full window height including browser UI

Practical — Detect Screen Size Category

function getDeviceType() {
  let width = window.innerWidth;

  if (width < 576)  return "📱 Mobile";
  if (width < 768)  return "📱 Large Mobile";
  if (width < 992)  return "📟 Tablet";
  if (width < 1200) return "💻 Laptop";
  return "🖥️ Desktop";
}

console.log(getDeviceType()); // e.g. "💻 Laptop"

// Listen for resize events
window.addEventListener("resize", () => {
  console.log(`Window resized: ${window.innerWidth} × ${window.innerHeight}`);
  console.log(`Device type: ${getDeviceType()}`);
});

Window Position and Scrolling

Scroll Position

console.log(window.scrollX); // How far scrolled horizontally (pixels)
console.log(window.scrollY); // How far scrolled vertically (pixels)

// Also available as:
console.log(window.pageXOffset); // Same as scrollX
console.log(window.pageYOffset); // Same as scrollY

Scroll Methods

// Scroll to a specific position
window.scrollTo(0, 500);   // x=0, y=500px from top

// Scroll smoothly
window.scrollTo({
  top:      500,
  left:     0,
  behavior: "smooth", // "smooth" or "auto"
});

// Scroll by an amount (relative)
window.scrollBy(0, 200);   // Scroll DOWN 200px from current position

window.scrollBy({
  top:      -200, // Scroll UP 200px
  behavior: "smooth",
});

// Scroll to top — classic "back to top" button
function scrollToTop() {
  window.scrollTo({ top: 0, behavior: "smooth" });
}

// Scroll to bottom
function scrollToBottom() {
  window.scrollTo({ top: document.body.scrollHeight, behavior: "smooth" });
}

Dialog Boxes

alert() — Show a Message

alert("Hello, Mihir! 👋");
alert("Your session is about to expire.");

confirm() — Ask Yes or No

Returns true if OK clicked, false if Cancel.

let confirmed = confirm("Are you sure you want to delete this item?");

if (confirmed) {
  console.log("Item deleted ✅");
} else {
  console.log("Deletion cancelled ❌");
}

prompt() — Ask for Input

Returns the entered string, or null if cancelled.

let name = prompt("What is your name?", "Mihir"); // second arg = default value

if (name) {
  console.log(`Hello, ${name}! 👋`);
} else {
  console.log("No name entered.");
}

⚠️ Use Sparingly

// ⚠️ Dialog boxes block the entire browser thread — use only for:
// - Quick debugging
// - Simple confirmations (before replacing with custom UI)

// ✅ In real projects, build custom modal dialogs instead
// alert/confirm/prompt are too basic for modern UIs

Timers

Timers are one of the most important features of window — they let you run code after a delay or repeatedly at an interval.

setTimeout() — Run Once After a Delay

// Syntax: setTimeout(callback, delayInMs)

let timerId = setTimeout(() => {
  console.log("This runs after 2 seconds");
}, 2000);

console.log("This runs immediately");
// Output:
// "This runs immediately"
// (2 seconds later...)
// "This runs after 2 seconds"

clearTimeout() — Cancel a Scheduled Timer

let timerId = setTimeout(() => {
  console.log("This will NOT run");
}, 3000);

// Cancel it before it fires
clearTimeout(timerId);
console.log("Timer cancelled ✅");

setInterval() — Run Repeatedly

// Syntax: setInterval(callback, intervalInMs)

let count = 0;
let intervalId = setInterval(() => {
  count++;
  console.log(`Count: ${count}`);

  if (count === 5) {
    clearInterval(intervalId); // Stop after 5 runs
    console.log("Interval stopped ✅");
  }
}, 1000);
// Output (one per second):
// Count: 1
// Count: 2
// Count: 3
// Count: 4
// Count: 5
// Interval stopped ✅

clearInterval() — Stop a Repeating Timer

let intervalId = setInterval(() => {
  console.log("Running...");
}, 1000);

// Stop after 5 seconds
setTimeout(() => {
  clearInterval(intervalId);
  console.log("Stopped!");
}, 5000);

Practical — Countdown Timer

function startCountdown(seconds, onTick, onComplete) {
  let remaining = seconds;

  onTick(remaining); // Show initial value immediately

  let intervalId = setInterval(() => {
    remaining--;
    onTick(remaining);

    if (remaining <= 0) {
      clearInterval(intervalId);
      onComplete();
    }
  }, 1000);

  return intervalId; // Return so caller can cancel if needed
}

startCountdown(
  5,
  (s) => console.log(`⏳ ${s} seconds remaining...`),
  ()  => console.log("🎉 Time's up!")
);
// Output (one per second):
// ⏳ 5 seconds remaining...
// ⏳ 4 seconds remaining...
// ⏳ 3 seconds remaining...
// ⏳ 2 seconds remaining...
// ⏳ 1 seconds remaining...
// ⏳ 0 seconds remaining...
// 🎉 Time's up!

Debounce Pattern — Delay Execution Until Typing Stops

function debounce(fn, delay) {
  let timerId;

  return function(...args) {
    clearTimeout(timerId); // Reset timer on every call
    timerId = setTimeout(() => fn(...args), delay);
  };
}

// Usage — search input that only fires after user stops typing
let handleSearch = debounce((query) => {
  console.log(`Searching for: "${query}"`);
}, 500);

// Simulate typing rapidly
handleSearch("J");
handleSearch("Ja");
handleSearch("Jav");
handleSearch("Java");
handleSearch("JavaScript"); // Only this fires — 500ms after last call

Throttle Pattern — Limit How Often a Function Fires

function throttle(fn, limit) {
  let lastCall = 0;

  return function(...args) {
    let now = Date.now();
    if (now - lastCall >= limit) {
      lastCall = now;
      fn(...args);
    }
  };
}

// Usage — scroll handler that fires at most once per 200ms
let handleScroll = throttle(() => {
  console.log(`Scroll position: ${window.scrollY}px`);
}, 200);

window.addEventListener("scroll", handleScroll);

window.location — URL Information

// Current URL info
console.log(window.location.href);      // Full URL
console.log(window.location.origin);    // "https://example.com"
console.log(window.location.protocol); // "https:"
console.log(window.location.host);     // "example.com"
console.log(window.location.pathname); // "/javascript/dom-and-bom/window-object"
console.log(window.location.search);   // "?tab=examples"
console.log(window.location.hash);     // "#section-timers"

Navigate with location

// Navigate to a new URL
window.location.href = "https://example.com"; // Full redirect

// Reload the page
window.location.reload();

// Replace current URL (no back button entry)
window.location.replace("https://example.com");

Opening and Closing Windows

window.open() — Open a New Tab/Window

// Open a new tab
let newTab = window.open("https://example.com", "_blank");

// Open with specific size (opens as popup window)
let popup = window.open(
  "https://example.com",
  "myWindow",
  "width=800,height=600,scrollbars=yes"
);

window.close() — Close a Window

// Only works on windows opened by window.open()
let win = window.open("https://example.com", "_blank");
setTimeout(() => {
  win.close();
  console.log("Window closed ✅");
}, 3000);

window.localStorage and window.sessionStorage

While we covered JSON persistence earlier, localStorage and sessionStorage are properties of window.

// localStorage — persists across sessions
localStorage.setItem("theme", "dark");
console.log(localStorage.getItem("theme")); // "dark"
localStorage.removeItem("theme");
localStorage.clear(); // Remove all

// sessionStorage — cleared when tab closes
sessionStorage.setItem("tempData", "session-value");
console.log(sessionStorage.getItem("tempData")); // "session-value"

Real-World Examples

Example 1: Back to Top Button Logic

// Show/hide a "back to top" button based on scroll position
window.addEventListener("scroll", () => {
  let backToTopBtn = document.getElementById("backToTop");
  if (!backToTopBtn) return;

  if (window.scrollY > 300) {
    backToTopBtn.style.display = "block";
  } else {
    backToTopBtn.style.display = "none";
  }
});

function scrollToTop() {
  window.scrollTo({ top: 0, behavior: "smooth" });
}

Example 2: Auto-Save Form with setInterval

function setupAutoSave(formId, intervalMs = 30000) {
  let form      = document.getElementById(formId);
  let lastSaved = null;

  let intervalId = setInterval(() => {
    let formData = {};

    // Collect all form fields
    for (let element of form.elements) {
      if (element.name) {
        formData[element.name] = element.value;
      }
    }

    localStorage.setItem("autosave_" + formId, JSON.stringify(formData));
    lastSaved = new Date().toLocaleTimeString();
    console.log(`💾 Auto-saved at ${lastSaved}`);
  }, intervalMs);

  // Clean up on page unload
  window.addEventListener("beforeunload", () => {
    clearInterval(intervalId);
  });

  return () => clearInterval(intervalId); // Return a stop function
}

// Usage
let stopAutoSave = setupAutoSave("contactForm", 5000); // Every 5s

// Stop when needed
// stopAutoSave();

Example 3: Session Timeout Warning

function setupSessionTimeout(timeoutMs = 300000, warningMs = 60000) {
  let warningTimer;
  let logoutTimer;

  function resetTimers() {
    clearTimeout(warningTimer);
    clearTimeout(logoutTimer);

    warningTimer = setTimeout(() => {
      let extend = confirm(
        "⚠️ Your session will expire in 1 minute.\n\nClick OK to stay logged in."
      );
      if (extend) resetTimers();
    }, timeoutMs - warningMs);

    logoutTimer = setTimeout(() => {
      alert("🔒 Session expired. You will be logged out.");
      window.location.href = "/login";
    }, timeoutMs);
  }

  // Reset on user activity
  ["mousemove", "keydown", "click", "scroll"].forEach(event => {
    window.addEventListener(event, resetTimers);
  });

  resetTimers(); // Start
  console.log("⏱️ Session timeout tracking started");
}

// setupSessionTimeout(300000, 60000); // 5 min timeout, warn at 4 min

Example 4: Responsive Layout Manager

function setupResponsiveManager(breakpoints = {
  mobile:  576,
  tablet:  992,
  desktop: 1200,
}) {
  function getLayout() {
    let w = window.innerWidth;
    if (w < breakpoints.mobile)  return "mobile";
    if (w < breakpoints.tablet)  return "tablet";
    if (w < breakpoints.desktop) return "laptop";
    return "desktop";
  }

  function applyLayout() {
    let layout = getLayout();
    document.body.setAttribute("data-layout", layout);
    console.log(`📐 Layout: ${layout} (${window.innerWidth}px)`);
  }

  // Apply on load
  applyLayout();

  // Apply on resize — throttled
  let throttled = throttle(applyLayout, 200);
  window.addEventListener("resize", throttled);
}

function throttle(fn, limit) {
  let lastCall = 0;
  return function(...args) {
    let now = Date.now();
    if (now - lastCall >= limit) {
      lastCall = now;
      fn(...args);
    }
  };
}

setupResponsiveManager();

Common Mistakes

Mistake 1: Polluting the Global Scope

// ❌ var at top level becomes window property — can clash with built-ins!
var screen   = "my screen";  // Overwrites window.screen!
var location = "/home";       // Overwrites window.location!

// ✅ Always use let or const — they don't attach to window
let screen   = "my screen";  // Block-scoped ✅
const path   = "/home";       // Block-scoped ✅

Mistake 2: Not Clearing Timers

// ❌ Setting interval without clearing — memory leak!
function startPolling() {
  setInterval(() => {
    console.log("Polling..."); // Runs forever, even if component is gone
  }, 1000);
}

// ✅ Always store the ID and clear when done
function startPolling() {
  let id = setInterval(() => {
    console.log("Polling...");
  }, 1000);

  return () => clearInterval(id); // Return cleanup function
}

let stop = startPolling();
setTimeout(stop, 5000); // Stop after 5 seconds ✅

Mistake 3: Using setTimeout(fn, 0) Expecting Immediate Execution

// ❌ setTimeout 0 does NOT run immediately
setTimeout(() => console.log("A"), 0);
console.log("B");

// Output:
// "B"  ← runs first
// "A"  ← runs after current call stack clears

// ✅ setTimeout(fn, 0) puts the callback in the event queue
// Use it intentionally to defer execution after current code completes

Mistake 4: window.open() Blocked by Browser

// ❌ Opening windows outside of user events gets blocked
setTimeout(() => {
  window.open("https://example.com"); // ❌ Blocked! — not a user action
}, 1000);

// ✅ Only open windows directly from user-triggered events
button.addEventListener("click", () => {
  window.open("https://example.com", "_blank"); // ✅ Allowed
});

Window Properties Cheat Sheet

Property / MethodWhat it does
window.innerWidthViewport width in pixels
window.innerHeightViewport height in pixels
window.outerWidthFull browser window width
window.outerHeightFull browser window height
window.scrollXCurrent horizontal scroll position
window.scrollYCurrent vertical scroll position
window.scrollTo(x, y)Scroll to position
window.scrollBy(x, y)Scroll by amount
window.locationURL info and navigation
window.location.hrefGet/set full URL
window.location.reload()Reload page
alert(msg)Show message dialog
confirm(msg)Show yes/no dialog
prompt(msg)Show input dialog
setTimeout(fn, ms)Run once after delay
clearTimeout(id)Cancel scheduled run
setInterval(fn, ms)Run repeatedly
clearInterval(id)Stop repeating run
window.open(url)Open new tab/window
window.close()Close current window
localStoragePersistent storage
sessionStorageSession-only storage

Key Takeaways

Congratulations! 🎉 You now fully understand the window object — the foundation of every browser-based JavaScript program.

window is the global object — all globals, DOM, and BOM features live inside it.

DimensionsinnerWidth/innerHeight for viewport size. outerWidth/outerHeight for full browser size.

ScrollingscrollTo() to absolute position, scrollBy() for relative movement. Add behavior: "smooth" for animation.

Dialogsalert(), confirm(), prompt() are simple but blocking. Replace with custom modals in real projects.

TimerssetTimeout() for one-time delay, setInterval() for recurring execution. Always store the ID so you can clearTimeout() / clearInterval().

Debounce — delay until user stops acting (search inputs). Throttle — limit frequency (scroll handlers).

location — read/change the URL, navigate, reload.

Never pollute window — use let/const, not var at top level.


Best Practices

  1. ✅ Always use let/const at the top level — never var which attaches to window
  2. ✅ Always store timer IDs — you'll need them to clear timers
  3. ✅ Always clear intervals when they're no longer needed — prevent memory leaks
  4. ✅ Use debounce on input handlers and throttle on scroll/resize handlers
  5. ✅ Prefer behavior: "smooth" for scrollTo/scrollBy — better user experience
  6. ✅ Only call window.open() inside user-triggered events — browsers block it otherwise
  7. ✅ Replace alert/confirm/prompt with custom modals in production apps
  8. ✅ Clean up event listeners and timers on page unload with beforeunload

What's Next?

Great work! 🎉 You now understand the browser's global object deeply.

Next up, let's explore how JavaScript interacts with the browser's navigation history:

History Object — navigate back and forward, push and replace URL states, and build single-page app navigation without full page reloads!

Let's keep going! 💪