JS Exercises, Quizzes & 30-Day Study Plan
Transform conceptual knowledge into muscle memory: solve senior-level algorithmic drills (Debounce, Deep Equality, EventEmitter), and track your progress through the structured 30-Day JavaScript Mastery Bootcamp.
The 30-Day JavaScript Mastery Progression Map
Follow a battle-tested daily progression curve from fundamental memory mechanics to production architectural design patterns.
1. Senior Engineering Coding Drills
Below are canonical implementation challenges frequently tested in senior frontend coding evaluations:
Drill 1: Production Debounce Function
Ensures a function runs only after a specified idle period has elapsed:
function debounce(fn, delayMs = 300) {
let timerId = null;
return function (...args) {
clearTimeout(timerId);
timerId = setTimeout(() => {
fn.apply(this, args);
}, delayMs);
};
}
// Usage:
// searchInput.addEventListener('input', debounce(performSearch, 400));
Run in Playground
Drill 2: Deep Object Equality Checker
function deepEqual(a, b) {
if (a === b) return true;
if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {
return false;
}
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
for (const key of keysA) {
if (!keysB.includes(key) || !deepEqual(a[key], b[key])) {
return false;
}
}
return true;
}
Test in Playground
Interactive Lab: 30-Day Progress Dashboard
0% CompleteCheck off the modules as you complete daily drills. Your progress is automatically persisted in your browser's local storage.
Build a Complete EventEmitter Class from Scratch
Implement a pub/sub EventEmitter with on(event, listener), emit(event, ...args), off(event, listener), and once(event, listener).
class EventEmitter {
constructor() {
this.events = new Map();
}
on(event, listener) {
if (!this.events.has(event)) {
this.events.set(event, []);
}
this.events.get(event).push(listener);
return () => this.off(event, listener); // Unsubscribe helper
}
off(event, listener) {
const listeners = this.events.get(event);
if (!listeners) return;
this.events.set(event, listeners.filter(fn => fn !== listener));
}
emit(event, ...args) {
const listeners = this.events.get(event);
if (!listeners) return;
listeners.forEach(fn => fn(...args));
}
once(event, listener) {
const wrapper = (...args) => {
this.off(event, wrapper);
listener(...args);
};
return this.on(event, wrapper);
}
}
Chapter 39 Knowledge Check
Validate your mastery of core design patterns, debounce/throttle mechanics, and pub/sub architecture.
a === b evaluate to false?