Reflect
Introduction
Reflect is a built-in object containing methods that mirror JavaScript's fundamental object operations: get, set, has, delete, apply, construct, defineProperty, ownKeys, and more.
It is most valuable when paired with Proxy traps because it forwards default behavior using the same internal operation that ordinary syntax would use.
Why This Matters
Reflect turns metaprogramming into explicit function calls. Interviewers expect you to know why Proxy examples call Reflect.get or Reflect.set, and how Reflect methods differ from older APIs that throw or return different values.
Theory
Reflect as operation functions
Many JavaScript operations have syntax forms: property access, the in operator, deletion, function application, and construction. Reflect exposes these as functions.
Better return values
Some Reflect methods return booleans instead of throwing for normal failure. Reflect.set and Reflect.defineProperty return whether the operation succeeded, which is useful inside traps.
Pairing with Proxy
Every major Proxy trap has a corresponding Reflect method. The common pattern is intercept, add behavior, then call the matching Reflect method to preserve default semantics.
Receiver matters
Reflect.get(target, property, receiver) and Reflect.set(target, property, value, receiver) preserve correct this behavior for getters and setters along the prototype chain. Direct target access does not always do that. Reflect is a namespace object, not a constructor.
Visual Diagrams
Proxy trap receives operation | add logging or validation v Reflect.method performs default operation | trap returns Reflect result
Reflect keeps custom traps aligned with normal JavaScript semantics.
Code Examples
Reflect operations as functions
These calls mirror common syntax while returning values useful for metaprogramming.
Default forwarding inside a proxy
The matching Reflect method avoids reimplementing JavaScript's object semantics by hand.
Playground
Press Run to execute the code and see output here.
Output Prediction
Predict the output #1
1var target = { name: 'Ada' };2 3console.log(Reflect.has(target, 'name'));4console.log(Reflect.get(target, 'missing'));5console.log(Reflect.set(target, 'role', 'engineer'));6console.log(target.role);7 8function add(a, b) {9 return a + b;10}11 12console.log(Reflect.apply(add, null, [2, 5]));Coding Exercises
Create an audited object with Reflect forwarding
MediumImplement createAuditedObject(target) that returns { proxy, log }. The proxy should log get, set, has, and deleteProperty operations, then forward each operation using the matching Reflect method.
Interview Questions
1Why is Reflect commonly used inside Proxy traps?
Reflect provides function forms of the default internal operations. Calling the matching Reflect method inside a trap forwards the operation with correct semantics for prototypes, accessors, receivers, and boolean success values.
Follow-ups
- What does the receiver argument do?
- How is `Reflect.apply` different from older apply patterns?
2Is Reflect a class or constructor?
No. Reflect is a namespace-like built-in object containing static methods. You do not instantiate it.
Quiz
1. Which Reflect method calls a function with an explicit `this` value and argument list?
Summary
- Reflect exposes fundamental object operations as functions.
- Most Proxy traps have matching Reflect methods for default forwarding.
- Reflect methods often return useful booleans for success or failure.
- `Reflect.get` and `Reflect.set` preserve receiver semantics for accessors and prototypes.
Cheat Sheet
Common methods: get, set, has, deleteProperty, ownKeys, apply, construct, defineProperty.
Proxy pattern: trap → custom logic → matching Reflect call.
Benefits: explicit operations, correct receiver semantics, useful boolean returns.
Not: a constructor or replacement for all object APIs.