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 areaFull Browser Size (Including Toolbars)
console.log(window.outerWidth); // Full window width including browser UI
console.log(window.outerHeight); // Full window height including browser UIPractical — 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 scrollYScroll 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 UIsTimers
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 callThrottle 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 minExample 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 completesMistake 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 / Method | What it does |
|---|---|
window.innerWidth | Viewport width in pixels |
window.innerHeight | Viewport height in pixels |
window.outerWidth | Full browser window width |
window.outerHeight | Full browser window height |
window.scrollX | Current horizontal scroll position |
window.scrollY | Current vertical scroll position |
window.scrollTo(x, y) | Scroll to position |
window.scrollBy(x, y) | Scroll by amount |
window.location | URL info and navigation |
window.location.href | Get/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 |
localStorage | Persistent storage |
sessionStorage | Session-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.
✅ Dimensions — innerWidth/innerHeight for viewport size. outerWidth/outerHeight for full browser size.
✅ Scrolling — scrollTo() to absolute position, scrollBy() for relative movement. Add behavior: "smooth" for animation.
✅ Dialogs — alert(), confirm(), prompt() are simple but blocking. Replace with custom modals in real projects.
✅ Timers — setTimeout() 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
- ✅ Always use
let/constat the top level — nevervarwhich attaches towindow - ✅ Always store timer IDs — you'll need them to clear timers
- ✅ Always clear intervals when they're no longer needed — prevent memory leaks
- ✅ Use
debounceon input handlers andthrottleon scroll/resize handlers - ✅ Prefer
behavior: "smooth"forscrollTo/scrollBy— better user experience - ✅ Only call
window.open()inside user-triggered events — browsers block it otherwise - ✅ Replace
alert/confirm/promptwith custom modals in production apps - ✅ 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! 💪