Classes vs Prototypes
🎭 Two Syntaxes, One Mechanism
ES6 classes are syntactic sugar over JavaScript's existing prototype-based inheritance. They don't introduce new inheritance model, but provide cleaner syntax.
Transformation: Class → Prototype
ES6 Class Syntax
class Animal {
constructor(name) {
this.name = name;
}
eat() {
return 'eating';
}
static isAnimal(obj) {
return obj instanceof Animal;
}
}
class Dog extends Animal {
bark() {
return 'woof';
}
}Equivalent Prototype Code
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function() {
return 'eating';
};
Animal.isAnimal = function(obj) {
return obj instanceof Animal;
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(
Animal.prototype
);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
return 'woof';
};Example 1: ES6 Classes - Modern Syntax
JavaScript Editor
✅ Advantages of ES6 Classes
Readability
- Clean, familiar syntax
- Less boilerplate
- Clear inheritance with
extends - Built-in getters/setters
Features
- Private fields (ES2022)
- Static methods and properties
- Method shorthand syntax
- Super keyword for parent access
Tooling
- Better IDE support
- TypeScript compatibility
- Modern framework support
- Better documentation
Example 2: Constructor Functions - Traditional Approach
JavaScript Editor
⚠️ When to Use Constructor Functions
Advantages
- Maximum browser compatibility
- More control over prototype chain
- Closures for true privacy
- No transpilation needed
- Familiar to legacy codebases
Disadvantages
- Verbose syntax
- Easy to make mistakes
- No built-in private fields
- Inheritance is cumbersome
- Less intuitive for OOP developers
Example 3: Performance Comparison
JavaScript Editor
📊 Performance Results Summary
| Operation | Classes | Constructors | Factory Functions | Winner |
|---|---|---|---|---|
| Instantiation | Fast | Fast | Slowest | Classes/Constructors |
| Method Calls | Fastest | Fast | Medium | Classes |
| Memory Usage | Medium | Medium | Highest | Classes/Constructors |
| Inheritance | Optimized | Manual | N/A | Classes |
| Encapsulation | Good (ES2022+) | Best (closures) | Best (closures) | Constructors/Factories |
Example 4: When to Use Which Pattern
JavaScript Editor
Exercise: Convert Between Patterns
JavaScript Editor
💡 Modern JavaScript Recommendations
- Use ES6 classes for most OOP scenarios (cleaner, better performance)
- Use constructor functions only for legacy browser support
- Use factory functions for functional programming patterns
- Use composition over inheritance when possible
- Consider TypeScript for better type safety with classes
- Use private fields (#) for true encapsulation (ES2022+)
- Benchmark performance for critical code paths
🎯 Interview Questions: Classes vs Prototypes
- What happens when you extend a class in JavaScript?
- How do private fields (#) work in ES6 classes?
- What's the difference between static methods in classes vs constructors?
- How does
super()work in classes? - Can you achieve true encapsulation in constructor functions?
- What are the performance implications of classes vs constructors?
- How would you implement multiple inheritance in JavaScript?
- What happens if you forget
newwith a constructor function? - How do getters and setters work in classes?
- What are the trade-offs between factory functions and classes?
🔧 Migration Guide: Constructor Functions → Classes
| Constructor Pattern | ES6 Class Equivalent | Notes |
|---|---|---|
function User() | class User | Basic conversion |
User.prototype.method | Method inside class | No prototype syntax needed |
function Child() Parent.call(this); | class Child extends Parent constructor() { super(); } | Use extends and super() |
Object.create(Parent.prototype) | extends keyword | Automatic prototype setup |
| Closure for privacy | Private fields (#field) | ES2022+ feature |
User.staticMethod | static staticMethod() | Inside class declaration |
Object.defineProperty getter/setter | get prop() / set prop() | Syntactic sugar |