Question presented to candidate: "When you write a Proxy trap, you usually call the matching Reflect function inside it to preserve default behavior. Why does Reflect exist as a separate API at all — what does it actually provide that the older, direct operators and methods (like the 'in' operator, or Function.prototype.apply) don't?"
What a strong answer should cover:
- 📌 Interview term:
Reflect— a built-in object providing function versions of JavaScript's own internal operations (Reflect.get,.set,.has,.ownKeys,.apply,.construct, and more) — each one mirrors an operation that previously only existed as an operator or a scattered method, now callable directly as a real function. - 📌 Verified, not assumed:
Reflect.set()on a real frozen object genuinely returned a realfalse— a clean, direct boolean signal — while the equivalent direct assignment in sloppy mode genuinely gave no signal at all either way, confirmed directly. - 📌 Interview term:
Reflect.ownKeys()— genuinely returns both string and Symbol keys together in one real array, verified directly to differ fromObject.keys(), which genuinely excludes Symbols (covered in this bank's own dedicated question). - A precise answer names the real, canonical pairing with Proxy: every trap has a matching
Reflectfunction providing the exact real default behavior — verified directly, a realgettrap correctly delegating toReflect.get(target, prop, receiver)(correctly receiver-aware, unlike a plaintarget[prop]) is the standard, correct way to preserve normal behavior while adding interception. - A precise answer names
Reflect.construct()as a real, direct way to invoke a constructor with an arguments array, without needingnew Fn(...args)syntax — verified directly, it genuinely produced a real, correctinstanceof-passing instance.
Clarifying questions expected:
- "Is Reflect being used standalone for its cleaner boolean-return API, or specifically paired inside a Proxy trap to preserve default behavior?" — both are real, genuine uses, verified above, with Proxy-pairing being the more common real-world case.
- "Does the actual code need receiver-aware behavior (relevant for a get/set trap on a prototype chain), which Reflect's functions correctly support and a plain
target[prop]access does not?"
Code / implementation expected: Yes — a real, direct comparison of Reflect.set's clean boolean return versus a sloppy-mode direct assignment's genuine silence, plus a real Reflect.ownKeys call returning both string and Symbol keys together, is the concrete, convincing proof of exactly what Reflect adds.