← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Proxy & Reflect API

JavaScript ES2015 Advanced
debt(d7/e5/b6/t8)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). ESLint and TypeScript can flag *missing* Reflect usage or obvious Proxy misconfigurations, but the detection_hints explicitly state 'automated: no'. Silent infinite loops, incorrect 'this' binding, and subtle trap-firing side effects require runtime observation or deep code review to catch.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix describes using Proxy + Reflect for transparent interception, which requires identifying all property-access points, updating traps (Reflect.get/set/etc.), and potentially refactoring method calls to preserve 'this'. Common mistakes like handling sealed objects or preventing infinite loops are per-proxy fixes, but the pattern shift is non-trivial.

b6 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b6, between b5 and b7). Proxy/Reflect appears in web and cli contexts; once introduced as the reactivity or validation layer (Vue 3, MobX, custom frameworks), every future maintainer must understand metaprogramming traps, trap semantics, and Reflect forwarding. The reach is broad (affects all components using the proxied object), but not architectural rewrite-or-live-with-it (b9) unless it becomes the system's core reactivity model.

t8 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception directly contradicts the common belief that Proxy is 'only for experts'—yet Vue 3 uses it transparently. Common_mistakes reveal multiple t7/t8 behaviors: returning false from set traps silently fails in non-strict but throws in strict mode; Proxy traps fire for *every* access (including internal), not just explicit ones; 'this' binding breaks with class instances; sealed/frozen objects throw TypeError. Developers familiar with property getters/setters or simple interception will guess wrong.

About DEBT scoring →

Also Known As

ES6 Proxy Reflect metaprogramming

TL;DR

Proxy wraps an object and intercepts fundamental operations (get, set, delete) via handler traps — Reflect provides the default implementations of those operations.

Explanation

new Proxy(target, handler) creates a proxy that intercepts operations on the target. The handler object defines traps: get (property access), set (property assignment), has (in operator), apply (function call), construct (new operator). Reflect provides corresponding static methods (Reflect.get, Reflect.set) that mirror the trapped operations, useful for forwarding in handlers. Proxy powers Vue 3's reactivity system, validation libraries, and mock frameworks.

Common Misconception

Proxy is only for metaprogramming experts — it is the foundation of Vue 3 reactivity; understanding it explains why Vue 3's reactivity is transparent.

Why It Matters

Proxy enables transparent reactivity, validation, and access control on any object without modifying the original — the mechanism behind Vue 3, MobX, and many testing utilities.

Common Mistakes

  • Not using Reflect.set/Reflect.get inside traps — returning false from a set trap triggers a TypeError in strict mode.
  • Proxying sealed or frozen objects — throws TypeError since the proxy cannot intercept property changes.
  • Not considering that Proxy traps fire for every access, including internal operations — can cause infinite loops if not careful.
  • Proxying class instances without handling 'this' — some methods break if 'this' is not the target, not the proxy.

Code Examples

✗ Vulnerable
// Manual validation on every setter — verbose and easy to miss:
class User {
    setEmail(email) {
        if (!email.includes('@')) throw new Error('Invalid');
        this._email = email;
    }
    setAge(age) {
        if (age < 0) throw new Error('Invalid');
        this._age = age;
    }
    // Must remember to add validation to every setter
}
✓ Fixed
// Proxy — intercept all property assignments:
const validators = { email: v => v.includes('@'), age: v => v >= 0 };

const validated = (obj) => new Proxy(obj, {
    set(target, prop, value) {
        if (validators[prop] && !validators[prop](value)) {
            throw new TypeError(`Invalid value for ${prop}: ${value}`);
        }
        return Reflect.set(target, prop, value); // Default set behaviour
    }
});

const user = validated({});
user.email = 'alice@example.com'; // OK
user.email = 'not-an-email'; // TypeError: Invalid value for email

Added 15 Mar 2026
Edited 22 Mar 2026
Views 115
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping F 1 ping S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 2 pings M 1 ping T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 2 pings T 0 pings W 1 ping T 0 pings F 2 pings S 0 pings S 0 pings M 1 ping T 3 pings W 1 ping T 0 pings F 0 pings S
No pings yet today
No pings yesterday
SEMrush 13 Amazonbot 10 PetalBot 9 Perplexity 7 Ahrefs 7 ChatGPT 7 Scrapy 7 Google 5 Unknown AI 4 Twitter/X 3 Bing 3 Applebot 2 Majestic 1 Meta AI 1 Brave Search 1 Sogou 1
crawler 75 crawler_json 5 pre-tracking 1
🧱 FUNDAMENTALS — new to this? Start with the ground floor.
JavaScript javascript The programming language of the browser — it reads and modifies the page (the DOM), reacts to user events, and fetches data without reloading.

JavaScript is the only language browsers execute, so every interactive behaviour on the web goes through it. Its two defining traits — single-threaded event loop and loose typing (== coercion) — explain the majority of both its bugs and its design patterns.

💡 Default to const, use === always, and reach for let only when a value genuinely reassigns.

Ask Codex about JavaScript →
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: High
⚡ Quick Fix
Use Proxy for transparent interception of object operations (validation, logging, lazy loading) and Reflect for proper forwarding — together they enable PHP-like __get/__set magic in JavaScript
📦 Applies To
javascript ES2015 web cli
🔗 Prerequisites
🔍 Detection Hints
Manual property access validation scattered across codebase; no interception layer for object operations; missing use of Reflect in Proxy traps
Auto-detectable: ✗ No eslint typescript
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: File Tests: Update


✓ schema.org compliant