Skip to content

Proxy vs Reflect

我们可以从 3W1H(What、Why、When、How)角度来系统性地理解 JavaScript 中的 ProxyReflect

🧠 1. What 是什么?

🔹 Proxy

Proxy 是 ES6 引入的一个构造函数,用于创建一个对象的代理,可以在对该对象进行操作时(如读写属性、函数调用、构造等)进行拦截并自定义行为。

js
const proxy = new Proxy(target, handler)

其中 target 是被代理的对象,handler 是定义拦截行为的对象。


🔹 Reflect

Reflect 是一个内置对象,它提供了一组用于操作对象的静态方法,对象的底层操作(如属性读取、设置、删除、函数调用等)都可以通过 Reflect 来完成,通常和 Proxy 一起使用。

js
Reflect.get(target, property, receiver)

🎯 2. Why 为什么需要?

🔹 Proxy 的目的

  • 自定义对象操作行为(如属性访问、赋值、函数调用等)
  • 实现数据绑定(如 Vue3 的响应式系统)
  • 实现访问控制、安全校验
  • mock 数据、拦截日志打印等

🔹 Reflect 的目的

  • 提供更一致的对象操作 API(如替代 Object.definePropertyobj[prop] = value 等)
  • 与 Proxy 配合使用,实现默认行为更方便(避免手动重复实现目标行为)
  • 提高代码可读性,像函数一样使用原生行为

🕒 3. When 什么时候使用?

场景使用 Proxy使用 Reflect
想拦截对象的读写行为
想优雅实现默认行为✅ (配合 Reflect)
想动态添加验证、权限控制等
替代旧的对象操作方法(如 Object.defineProperty)
编写通用库或框架底层封装

⚙️ 4. How 如何使用?

示例:使用 Proxy 和 Reflect 拦截属性访问

js
const target = { name: 'Flash', age: 30 }

const proxy = new Proxy(target, {
  get(target, key, receiver) {
    console.log(`访问属性: ${key}`)
    return Reflect.get(target, key, receiver) // 保留原始行为
  },
  set(target, key, value, receiver) {
    console.log(`设置属性: ${key} = ${value}`)
    return Reflect.set(target, key, value, receiver) // 保留原始行为
  }
})

proxy.name         // 控制台输出: 访问属性: name
proxy.age = 31     // 控制台输出: 设置属性: age = 31

✅ 总结对比

对比项ProxyReflect
类型构造函数内置对象
功能拦截对象行为,定义自定义逻辑执行默认对象操作
用法创建代理对象,对目标对象包装提供与 Proxy 拦截方法对应的原始操作
常见用途数据劫持、校验、封装逻辑配合 Proxy 保留默认行为
ES 版本ES6ES6