Proxy & Reflect API Deep Dive0%

Proxy & Reflect API Deep Dive

Beginner12 min read•Updated: Jul 11, 2026
Study Materials

Proxy & Reflect API Deep Dive in Modern JavaScript

Introduced in ECMAScript 2015 (ES6), the Proxy and Reflect APIs provide low-level metaprogramming capabilities in JavaScript. While standard objects only allow reading and writing properties, Proxy enables wrapping an object to intercept and redefine 13 fundamental language operations (termed Traps).


1. The 13 Proxy Traps and Their Reflect Equivalents

Every trap in a Proxy handler mirrors a corresponding static method on the built-in Reflect object:

Proxy TrapInterceptsTriggered ByReflect Method
getProperty accessobj.prop, obj['prop']Reflect.get()
setProperty assignmentobj.prop = valReflect.set()
hasThe in operator'prop' in objReflect.has()
deletePropertyDeleting a propertydelete obj.propReflect.deleteProperty()
applyFunction callfn(...args), fn.apply()Reflect.apply()
constructThe new operatornew MyClass()Reflect.construct()
getPrototypeOfGetting prototypeObject.getPrototypeOf()Reflect.getPrototypeOf()
setPrototypeOfSetting prototypeObject.setPrototypeOf()Reflect.setPrototypeOf()
isExtensibleExtensibility checkObject.isExtensible()Reflect.isExtensible()
preventExtensionsDisabling extensionsObject.preventExtensions()Reflect.preventExtensions()
getOwnPropertyDescriptorInspecting descriptorsObject.getOwnPropertyDescriptor()Reflect.getOwnPropertyDescriptor()
definePropertyDefining descriptorsObject.defineProperty()Reflect.defineProperty()
ownKeysEnumerating keysObject.keys(), Object.getOwnPropertyNames()Reflect.ownKeys()

2. Why Reflect is Mandatory Inside Proxy Traps

A common beginner mistake is directly calling target[prop] inside a get trap:

JavaScript
// ANTI-PATTERN: Breaks inheritance when prototype objects access getters!
get(target, prop) {
return target[prop]; // 'this' inside getters will point to target, NOT receiver!
}
 
// CORRECT STANDARD PATTERN:
get(target, prop, receiver) {
return Reflect.get(target, prop, receiver); // Correctly binds 'this' to the Proxy!
}

The receiver parameter guarantees that if a property is a getter that uses this, this correctly points to the Proxy instance, not the underlying raw target object!


3. Real-World Architectural Implementations

1. Reactive Data Binding (Vue 3 Reactivity Engine)

JavaScript
function reactive(target, onChange) {
return new Proxy(target, {
set(target, prop, value, receiver) {
const oldValue = target[prop];
const result = Reflect.set(target, prop, value, receiver);
 
if (oldValue !== value) {
onChange(prop, value, oldValue); // Notify UI to re-render!
}
return result;
}
});
}
 
const state = reactive({ count: 0 }, (prop, val) => {
console.log(`[Reactivity] Property "${prop}" changed to: ${val}`);
});
 
state.count = 1; // Logs: [Reactivity] Property "count" changed to: 1

2. Negative Array Indexing (Python-Style Arrays)

In JavaScript, arr[-1] returns undefined. We can implement Python-style negative indices using Proxy:

JavaScript
function createSmartArray(...items) {
return new Proxy(items, {
get(target, prop, receiver) {
if (typeof prop === 'string') {
const index = Number(prop);
if (!isNaN(index) && index < 0) {
// Translate -1 to (length - 1)
const resolvedIndex = target.length + index;
return Reflect.get(target, resolvedIndex, receiver);
}
}
return Reflect.get(target, prop, receiver);
}
});
}
 
const list = createSmartArray('A', 'B', 'C', 'D');
console.log(list[-1]); // 'D' (Last element!)
console.log(list[-2]); // 'C'

4. Revocable Proxies (Proxy.revocable())

A Revocable Proxy creates a proxy that can be completely disconnected and disabled at any time, instantly cutting off access:

JavaScript
const sensitiveData = { apiKey: 'SECRET_4920' };
const { proxy, revoke } = Proxy.revocable(sensitiveData, {});
 
console.log(proxy.apiKey); // 'SECRET_4920'
 
// Revoke access when session ends:
revoke();
 
// Subsequent access throws TypeError!
// console.log(proxy.apiKey); // TypeError: Cannot perform 'get' on a proxy that has been revoked!

Interactive Quiz

Practice Quiz

Question 1
How many fundamental internal operation traps can be intercepted by a JavaScript Proxy?
Question 2
Why is the receiver argument passed to Reflect.get(target, prop, receiver)?
Question 3
What happens when code attempts to access a property on a revoked Proxy (created via Proxy.revocable())?
Question 4
Which Proxy trap intercepts the "in" operator (e.g. 'prop' in obj)?
Question 5
What modern frontend framework uses JavaScript Proxies as the core foundation of its fine-grained reactivity system?
Next Lesson

Metaprogramming in JavaScript

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext