Code
JavaScript Examples
Useful patterns and utilities I use regularly. Copy freely.
⏱️
Debounce Function
Limit how often a function fires — essential for search inputs and resize handlers.
debounce.js
function debounce(fn, delay = 300) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// Usage
const search = debounce((query) => {
console.log('Searching for:', query);
}, 500);
// Rapid calls only fire once after 500ms pause
search('h');
search('he');
search('hello'); // Only this one runs📋
Deep Clone
Create a true deep copy of any object without shared references.
deep-clone.js
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
if (Array.isArray(obj)) return obj.map(deepClone);
const cloned = {};
for (const key of Object.keys(obj)) {
cloned[key] = deepClone(obj[key]);
}
return cloned;
}
// Usage
const original = {
name: 'Alice',
scores: [95, 87, 92],
meta: { joined: new Date() },
};
const copy = deepClone(original);
copy.scores.push(100);
console.log(original.scores); // [95, 87, 92] — unaffected!📡
Event Emitter
A lightweight pub/sub system for decoupled communication between modules.
event-emitter.js
class EventEmitter {
constructor() {
this.events = {};
}
on(event, listener) {
(this.events[event] ||= []).push(listener);
return () => this.off(event, listener);
}
off(event, listener) {
this.events[event] = this.events[event]
?.filter((fn) => fn !== listener);
}
emit(event, ...args) {
this.events[event]?.forEach((fn) => fn(...args));
}
}
// Usage
const bus = new EventEmitter();
const unsub = bus.on('message', (msg) => {
console.log('Received:', msg);
});
bus.emit('message', 'Hello!'); // "Received: Hello!"
unsub(); // Unsubscribe
bus.emit('message', 'Goodbye'); // Nothing happens🚦
Throttle Function
Ensure a function runs at most once per interval — ideal for scroll and resize events.
throttle.js
function throttle(fn, interval = 300) {
let lastTime = 0;
let timer = null;
return function (...args) {
const now = Date.now();
const remaining = interval - (now - lastTime);
if (remaining <= 0) {
clearTimeout(timer);
lastTime = now;
fn.apply(this, args);
} else if (!timer) {
timer = setTimeout(() => {
lastTime = Date.now();
timer = null;
fn.apply(this, args);
}, remaining);
}
};
}
// Usage — fires at most once per 200ms
window.addEventListener(
'scroll',
throttle(() => console.log('Scrolled!'), 200)
);🏊
Promise Pool
Run async tasks with a concurrency limit to avoid overwhelming APIs.
promise-pool.js
async function promisePool(tasks, concurrency = 3) {
const results = [];
let index = 0;
async function worker() {
while (index < tasks.length) {
const i = index++;
results[i] = await tasks[i]();
}
}
const workers = Array.from(
{ length: Math.min(concurrency, tasks.length) },
() => worker()
);
await Promise.all(workers);
return results;
}
// Usage — fetch 10 URLs, 3 at a time
const urls = Array.from({ length: 10 }, (_, i) =>
() => fetch(`/api/item/${i}`).then((r) => r.json())
);
const results = await promisePool(urls, 3);⚡
Reactive State
A minimal reactive state system using JavaScript Proxies.
reactive-state.js
function reactive(initial, onChange) {
return new Proxy(initial, {
set(target, key, value) {
const old = target[key];
target[key] = value;
if (old !== value) {
onChange(key, value, old);
}
return true;
},
});
}
// Usage
const state = reactive({ count: 0, name: 'World' }, (key, val, old) => {
console.log(`${key} changed: ${old} → ${val}`);
});
state.count = 1; // "count changed: 0 → 1"
state.name = 'JS'; // "name changed: World → JS"
state.count = 1; // No log — value didn't change