Difficulty: Intermediate
What are common design patterns used in JavaScript? Give examples of each.
Key JavaScript design patterns:
Observer/PubSub: objects subscribe to events, decoupling publishers from subscribers. Foundation of event emitters and reactive programming.
Singleton: ensures only one instance of a class exists. Common for stores, loggers, database connections.
Factory: creates objects without exposing instantiation logic. Useful when the type of object varies based on conditions.
Strategy: defines interchangeable algorithms behind a common interface. Useful for sorting strategies, payment methods.
Module: encapsulates private state using closures or ES modules.
class EventEmitter {
constructor() { this._events = {}; }
on(event, listener) {
if (!this._events[event]) this._events[event] = [];
this._events[event].push(listener);
return this;
}
off(event, listener) {
this._events[event] = (this._events[event] || [])
.filter(l => l !== listener);
return this;
}
emit(event, ...args) {
(this._events[event] || []).forEach(l => l(...args));
}
once(event, listener) {
const wrapper = (...args) => {
listener(...args);
this.off(event, wrapper);
};
return this.on(event, wrapper);
}
}
const emitter = new EventEmitter();
emitter.on('data', (msg) => console.log('Received:', msg));
emitter.once('connect', () => console.log('Connected!'));
emitter.emit('connect');
emitter.emit('connect');
emitter.emit('data', 'Hello');
The Observer pattern decouples event producers from consumers. once() auto-removes after first call.
const Logger = (() => {
let instance;
return {
getInstance() {
if (!instance) {
instance = {
logs: [],
log(msg) {
this.logs.push(msg);
console.log(`[LOG] ${msg}`);
}
};
}
return instance;
}
};
})();
const l1 = Logger.getInstance();
const l2 = Logger.getInstance();
console.log(l1 === l2);
l1.log('App started');
console.log(l2.logs);
function createAnimal(type) {
const animals = {
dog: () => ({ sound: () => 'Woof', legs: 4 }),
bird: () => ({ sound: () => 'Tweet', legs: 2 })
};
if (!animals[type]) throw new Error(`Unknown type: ${type}`);
return animals[type]();
}
console.log(createAnimal('dog').sound());
console.log(createAnimal('bird').legs);
Singleton ensures one instance via closure. Factory returns different implementations based on a parameter.
Observer, Singleton, Factory, Strategy, Module