Proxy and Reflect

Back

Loading concept...

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

  1. Create a Proxy around your object
  2. Define traps in the handler
  3. Use Reflect inside traps for default behavior
  4. 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! ๐Ÿš€

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.