What are Proxies in JavaScript?

JavaScript

Let's Talk About JavaScript Proxies!

Alright everyone, let's dive into one of JavaScript's most powerful and, honestly, coolest features: the Proxy.

Imagine you have a very important object, like a VIP. You don't want just anyone to be able to talk to or change this VIP. So, you hire a personal security guard or an agent. This agent stands in front of your VIP and intercepts every interaction. They check who is trying to talk to the VIP, what they want to say, and can even change the message.

In JavaScript, a Proxy is that security guard for your objects. It's a special object that wraps your original object and lets you intercept and control interactions with it.

The Two Key Ingredients

To create a Proxy, you always need two things:

  • The target: This is your original object—the VIP you want to protect.
  • The handler: This is an object that acts as the rulebook for your security guard. It contains special functions called "traps" that catch specific actions.

The most common traps you'll use are:

  • get: Catches when someone tries to read a property.
  • set: Catches when someone tries to change a property.

Let's see the most basic example:

// This is our 'target' object
const user = {
name: "Sam",
email: "sam@example.com"
};

// This is our 'handler' object with a 'get' trap
const handler = {
get(target, property) {
// We'll print a message every time a property is read
console.log(`Your code is trying to access the '${property}' property!`);
// Then, we'll allow the access
return target[property];
}
};

// Now, let's create our Proxy!
const userProxy = new Proxy(user, handler);

// Let's interact with the PROXY, not the original object
console.log(userProxy.name);

When you run this, you'll see:

Your code is trying to access the 'name' property!
Sam

See? Our get trap was triggered! We "intercepted" the action.

"Okay, but Why is this Useful?" (The Awesome Use Cases)

This is where the magic really happens. Here’s why Proxies are a game-changer and a hot topic in interviews.

Use Case #1: Making Sure Your Data is Always Valid

You can use the set trap to validate data before it ever touches your object. This is perfect for making sure your application's data stays clean.

Example: Let's make sure a user's age is always a positive number.

const user = { name: "Alex" };

const validationHandler = {
set(target, property, value) {
// We only care about the 'age' property for this rule
if (property === 'age') {
if (typeof value !== 'number' || value <= 0) {
// If the new value is not a positive number, stop it!
throw new Error('Whoa there! Age must be a positive number.');
}
}
// If everything is okay, go ahead and set the property
target[property] = value;
return true; // A 'set' trap should always return true on success
}
};

const userProxy = new Proxy(user, validationHandler);

userProxy.age = 30; // Works perfectly!
console.log(userProxy.age); // 30

// Now, try to do something invalid:
// userProxy.age = -10; // This will throw our custom error!

Use Case #2: The Magic Behind Modern Frameworks (like Vue!)

This is a HUGE deal. Modern frameworks like Vue use Proxies for their reactivity system. They wrap your data or state object in a Proxy. When you change a property, the set trap fires and tells the framework, "Hey! The data changed! You need to update the web page!"

Here’s a simplified idea of how it works:

// This function would normally update your website's HTML
function updateWebsite() {
console.log("UI is re-rendering with new data!");
}

const state = new Proxy({ score: 0 }, {
set(target, property, value) {
// First, update the actual data
target[property] = value;
// Then, trigger the UI update! This is reactivity!
updateWebsite();
return true;
}
});

// Now, any time you change the 'score'...
state.score = 10; // The UI update happens automatically!

When an interviewer asks how modern frameworks achieve reactivity, Proxies are a huge part of the answer!

Use Case #3: Playing Detective with Your Code (Logging)

Ever had a bug where a value changes, but you don't know where or why? A Proxy is the perfect detective. You can log every time a property is read or changed to trace your code's execution.

const loggingHandler = {
get(target, property) {
console.log(`Just accessed '${property}'`);
return target[property];
},
set(target, property, value) {
console.log(`Just changed '${property}' from '${target[property]}' to '${value}'`);
target[property] = value;
return true;
}
};

const settings = new Proxy({ theme: 'dark' }, loggingHandler);

settings.theme; // Logs: Just accessed 'theme'
settings.theme = 'light'; // Logs: Just changed 'theme' from 'dark' to 'light'

The Big Takeaway for Your Interviews

So, what should you remember?

A JavaScript Proxy gives you ultimate control over an object. It lets you wrap an object and use traps (like get and set) to intercept operations for validation, reactivity (state management), logging, and more.

It's a powerful tool for writing cleaner, more robust, and more "magical" code, and it's a fundamental concept behind the scenes of many modern libraries you use every day.

Good luck!

00:00