Object Creation Patterns
JavaScript offers several patterns for creating and organizing objects. Each pattern has its own use cases and trade-offs.
Factory Pattern
// Simple factory function
function createUser(name, age) {
return {
name,
age,
greet() {
return `Hello, I'm ${this.name}`;
}
};
}
const user1 = createUser('John', 30);
const user2 = createUser('Jane', 25);
// Factory with private variables
function createCounter() {
let count = 0; // Private variable
return {
increment() { return ++count; },
decrement() { return --count; },
getCount() { return count; }
};
}Constructor Pattern
// Constructor function
function User(name, age) {
this.name = name;
this.age = age;
}
User.prototype.greet = function() {
return `Hello, I'm ${this.name}`;
};
const user = new User('John', 30);
// Adding methods after creation
User.prototype.birthday = function() {
this.age++;
};
// ES6 Class syntax (same under the hood)
class UserClass {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, I'm ${this.name}`;
}
}Singleton Pattern
// Classic Singleton
const Database = (function() {
let instance;
function createInstance() {
return {
data: [],
add(item) { this.data.push(item); },
remove(item) { /* ... */ }
};
}
return {
getInstance() {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
// Usage
const db1 = Database.getInstance();
const db2 = Database.getInstance();
console.log(db1 === db2); // trueModule Pattern
// IIFE Module
const Calculator = (function() {
// Private variables
let result = 0;
// Private function
function validate(num) {
return typeof num === 'number';
}
// Public API
return {
add(num) {
if (validate(num)) result += num;
return result;
},
subtract(num) {
if (validate(num)) result -= num;
return result;
},
getResult() {
return result;
}
};
})();Common Interview Follow-up Questions
- What are the advantages of factory vs constructor pattern?
- How does prototypal inheritance work with these patterns?
- When would you use the Singleton pattern?
- How do you implement private properties in classes?
Best Practices
- Choose patterns based on specific needs
- Consider memory usage with prototypes
- Use modern class syntax when appropriate
- Implement proper encapsulation
- Keep objects focused and single-purpose