Objects: Proxy and Reflect - Your Magical Gatekeepers! ๐ฐ
The Story of the Secret Diary
Imagine you have a super special diary. But this diary has a magical guardianโa tiny wizard who sits on top of it. Every time someone tries to:
- Read a page โ the wizard checks first
- Write something โ the wizard approves it
- Erase a word โ the wizard decides if itโs okay
This magical wizard? Thatโs a Proxy in JavaScript!
And the wizard has a magic spell book called Reflect that helps him do his job perfectly.
๐ญ What is a Proxy Object?
A Proxy is like a bodyguard for your object. It stands between your object and the world, intercepting every action.
// Your original object (the diary)
const diary = {
secret: "I like cookies",
mood: "happy"
};
// Create a Proxy (the wizard guardian)
const guardedDiary = new Proxy(diary, {
get(target, property) {
console.log(`Someone is reading: ${property}`);
return target[property];
}
});
// Now when you read...
console.log(guardedDiary.secret);
// Output: "Someone is reading: secret"
// Output: "I like cookies"
Breaking It Down
| Part | What It Is | Likeโฆ |
|---|---|---|
target |
The original object | Your diary |
handler |
Rules for the proxy | The wizardโs instructions |
trap |
A specific rule | One spell the wizard knows |
๐ชค Proxy Traps - The Wizardโs Spell Book
Traps are the special powers your proxy guardian has. Each trap catches a different action!
The Most Common Traps
graph TD A["Someone Tries to Access Object"] --> B{Which Action?} B -->|Reading| C["get trap"] B -->|Writing| D["set trap"] B -->|Deleting| E["deleteProperty trap"] B -->|Checking existence| F["has trap"] C --> G["Proxy Decides"] D --> G E --> G F --> G
1. The get Trap - Reading Guard
Catches when someone reads a property.
const handler = {
get(target, property) {
if (property === "password") {
return "๐ Nice try! Secret!";
}
return target[property];
}
};
const user = new Proxy(
{ name: "Alex", password: "12345" },
handler
);
console.log(user.name); // "Alex"
console.log(user.password); // "๐ Nice try! Secret!"
2. The set Trap - Writing Guard
Catches when someone writes a property.
const handler = {
set(target, property, value) {
if (property === "age" && value < 0) {
console.log("Age can't be negative!");
return false;
}
target[property] = value;
return true;
}
};
const person = new Proxy({}, handler);
person.age = 25; // Works fine!
person.age = -5; // "Age can't be negative!"
3. The has Trap - Existence Checker
Catches when someone uses in to check if a property exists.
const handler = {
has(target, property) {
if (property.startsWith("_")) {
return false; // Hide private properties
}
return property in target;
}
};
const obj = new Proxy(
{ name: "visible", _secret: "hidden" },
handler
);
console.log("name" in obj); // true
console.log("_secret" in obj); // false (hidden!)
4. The deleteProperty Trap - Delete Guard
Catches when someone tries to delete a property.
const handler = {
deleteProperty(target, property) {
if (property === "important") {
console.log("Can't delete important!");
return false;
}
delete target[property];
return true;
}
};
const data = new Proxy(
{ important: "keep", temp: "remove" },
handler
);
delete data.temp; // Works!
delete data.important; // "Can't delete important!"
๐ Quick Trap Reference
| Trap | Catches Whenโฆ | Example |
|---|---|---|
get |
Reading a property | obj.name |
set |
Writing a property | obj.name = "X" |
has |
Checking with in |
"name" in obj |
deleteProperty |
Deleting | delete obj.name |
apply |
Calling a function | func() |
construct |
Using new |
new Func() |
โจ The Reflect API - The Wizardโs Perfect Helper
Reflect is like a perfect assistant that does exactly what would normally happen, but in a clean way.
Why Use Reflect?
Think of it this way:
- Without Reflect: You do things your own way (might make mistakes)
- With Reflect: You do things the official way (always correct)
const obj = { name: "Luna" };
// Old way (works but not as clean)
const value1 = obj.name;
// Reflect way (official and consistent)
const value2 = Reflect.get(obj, "name");
// Both give "Luna"!
Reflect Methods Match Traps
Every trap has a matching Reflect method!
graph LR A["get trap"] --> B["Reflect.get"] C["set trap"] --> D["Reflect.set"] E["has trap"] --> F["Reflect.has"] G["deleteProperty trap"] --> H["Reflect.deleteProperty"]
The Power Combo: Proxy + Reflect
const handler = {
get(target, property, receiver) {
console.log(`Reading ${property}`);
// Use Reflect to do the default action
return Reflect.get(target, property, receiver);
},
set(target, property, value, receiver) {
console.log(`Writing ${property} = ${value}`);
// Use Reflect to actually set the value
return Reflect.set(target, property, value, receiver);
}
};
const user = new Proxy(
{ name: "Max" },
handler
);
user.name; // "Reading name"
user.age = 10; // "Writing age = 10"
Key Reflect Methods
// Reading
Reflect.get(obj, "name"); // Like obj.name
// Writing
Reflect.set(obj, "name", "Sam"); // Like obj.name = "Sam"
// Checking existence
Reflect.has(obj, "name"); // Like "name" in obj
// Deleting
Reflect.deleteProperty(obj, "x");// Like delete obj.x
// Getting all keys
Reflect.ownKeys(obj); // Gets all property names
๐ฎ Real-World Example: A Smart Logger
Letโs build something coolโan object that logs everything!
function createLogger(target) {
return new Proxy(target, {
get(target, prop, receiver) {
console.log(`๐ GET: ${prop}`);
return Reflect.get(target, prop, receiver);
},
set(target, prop, value, receiver) {
console.log(`โ๏ธ SET: ${prop} = ${value}`);
return Reflect.set(target, prop, value, receiver);
},
deleteProperty(target, prop) {
console.log(`๐๏ธ DELETE: ${prop}`);
return Reflect.deleteProperty(target, prop);
}
});
}
// Use it!
const game = createLogger({
score: 0,
level: 1
});
game.score = 100; // โ๏ธ SET: score = 100
game.level; // ๐ GET: level
delete game.score; // ๐๏ธ DELETE: score
๐ง Remember This!
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PROXY = Bodyguard (intercepts actions) โ
โ TRAPS = The rules the bodyguard follows โ
โ REFLECT = The official way to do actions โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Simple Formula
- Create a Proxy around your object
- Define traps in the handler
- Use Reflect inside traps for default behavior
- Enjoy complete control over your object!
๐ก When to Use Proxy & Reflect?
| Use Case | How It Helps |
|---|---|
| Validation | Check values before setting |
| Logging | Track all object access |
| Security | Hide or protect properties |
| Default values | Return defaults for missing props |
| Reactive systems | Detect changes (like Vue.js!) |
๐ You Did It!
Now you understand:
- โ Proxy objects wrap around other objects
- โ Traps catch specific operations
- โ Reflect provides clean default behavior
- โ Together, they give you superpowers over objects!
Think of it like this: You just learned how to create your own magical guardian for any object. The guardian (Proxy) follows your rules (Traps) and uses official magic (Reflect) to get things done right!
Go build something amazing! ๐
