Design Patterns
Proxy Pattern
Master the Proxy Pattern in JavaScript. Learn to use proxy wrappers to control property access, implement caching, and intercept object operations.
1. Introduction
The Proxy Pattern is a structural design pattern that provides a surrogate or placeholder wrapper object to control access to a target object, intercepting operations like property get lookups or function calls.
2. Why It Matters
Direct access to objects can sometimes be problematic (for example, if loading the object from a database is slow, or if you need to check access permissions first). A proxy wrapper acts as a gatekeeper, implementing caching, access control, or lazy initialization without modifying the target object.
3. Real-World Analogy
Think of a Debit Card (Proxy):
- Target Object (The bank vault cash): Real cash stored inside a vault. Walking around with pockets full of physical coins is inconvenient and insecure.
- Proxy (Debit Card): A plastic card that represents your cash. When you pay for a meal (request operation), the shop slides the card. The card processor validates your pin code (authentication trap), checks if you have enough funds, and deducts the balance. The card acts as a placeholder for the actual cash vault.
4. Implementing the Proxy Pattern
In modern JavaScript, you can implement the Proxy pattern natively using the Proxy constructor. The handler defines traps to intercept operations on the target object:
5. Lazy Initialization Proxy
You can use a Proxy to delay loading a heavy object until it is actually needed, saving startup memory:
6. Practical Example
This script demonstrates using a Proxy to implement automatic caching for a slow math API object:
7. Common Mistakes
- Not returning true from the set trap in strict mode: The
settrap must return a boolean value indicating whether the assignment succeeded. Forgetting the return statement returnsundefined, which throws a TypeError in strict mode.
8. Quick Quiz
Q1: Which design pattern is directly supported in modern JavaScript by the global Proxy object?
A) Observer Pattern
B) Proxy Pattern
Answer: B — Modern JavaScript provides a native Proxy class that simplifies implementing the Proxy pattern.
9. Scenario-Based Challenge
The Read-Only Database Config Guardian:
An application config object has database properties: { port: 8080 }. To prevent developers from accidentally modifying settings at runtime, wrap the config in a Proxy that blocks all property assignments, throwing a TypeError. Write this guardian proxy handler.
10. Debugging Exercise
Explain why this proxy setter crashes with a stack overflow error, and how to fix it:
const config = { host: 'localhost' };
const proxy = new Proxy(config, { set(target, prop, value) { // Bug: mutating property on proxy recursively calls the setter trap! proxy[prop] = value; // recursion stack overflow! return true; } }); proxy.host = 'site.com';
View Solution
Diagnosis: Accessing proxy[prop] = value inside the set trap invokes the set trap again, causing infinite recursion and a stack overflow error.
Fix: Mutate the property on the target object directly, or use Reflect.set() to forward the assignment safely:
const proxy = new Proxy(config, {
set(target, prop, value, receiver) {
return Reflect.set(target, prop, value, receiver); // Forward assignment safely
}
});
11. Interview Questions
🟢 Q1: Compare the Proxy Pattern and the Decorator Pattern.
Answer: Both patterns act as wrappers around other objects but have different purposes:
• Decorator Pattern: Focuses on extending an object's behavior dynamically (e.g. adding new methods or properties) without modifying the base class.
• Proxy Pattern: Focuses on controlling or protecting access to the target object (e.g. checking permissions, caching data, or delaying initialization) without modifying its behavior interface.
12. Production Considerations
- • Performance Overhead: Proxies introduce a performance overhead because every property access traverses the trap handler logic. Avoid wrapping high-frequency objects (like array elements inside computational render loops) in Proxies.