JavaScript Proxy 拦截原理与实战解析

作者:纸飞机时间:2026-10-24 11:42:41浏览:526

本文深入解析 JavaScript 中 Proxy 对象的拦截原理,通过房屋中介案例类比代理模式。详细讲解 get 和 set 拦截器的具体用法,包括属性读取时的存在性校验以及属性赋值时的类型与范围限制,帮助开发者理解如何利用 Proxy 实现数据访问的控制与校验。

什么是代理模式

引入一个现实生活中的案例

作为普通用户,我们是否需要亲自参与房屋评估、办理繁琐的住房手续等全过程?显然并非如此。用户的核心诉求仅在于获取满意的居住结果,即提出需求并支付相应金额即可。

解决这一系列复杂流程的角色是“房屋中介”。该机构在房地产供求市场中,为交易标的提供评估、交易代理、咨询及后续服务,充当了供需双方之间的桥梁。

结合案例理解代理模式的定义

当某个对象因故不适合或无法被客户端直接引用时,可引入代理对象作为中介,由代理对象负责与目标对象交互。

代理模式的核心在于为客户端提供一层代理,使客户端无需关注底层具体实现过程,只需关注最终结果。代理对象负责处理中间复杂的业务逻辑。

什么是Proxy

Proxy 支持多种拦截操作,本文重点阐述 get(target, propKey, receiver) 和 set(target, propKey, value, receiver) 两种核心拦截器。

  • get 方法:用于拦截对象属性的读取操作;
  • set 方法:用于拦截对象属性的赋值操作。

get(target, propKey, receiver)

首先定义一个 Person 对象,该对象将被 Proxy 包裹,外部通过 Proxy 实例来访问 Person 对象的属性。


var person = {
    name: "kongsam",
    age: 21,
    hobbies: [
        "看动漫",
        "骑行",
        "玩游戏"
    ]
}

创建一个 Proxy 实例,用于拦截外部对 Person 对象的所有操作请求。


var proxy = new Proxy(person, {
    get: function (target, property) {
          // 打印target和property,查看里面到底是什么。
          console.log("target = ", target);
          console.log("property = ", property);
          // 判断外界访问的对象属性是否存在于目标对象中。
          if (property in target) {
                return target[property];
          } else {
                // 如果外界访问的对象属性不存在与目标对象中,抛出异常。
                throw new ReferenceError('Property "' + property + '" 不存在。');
          }
    },
});

当执行 proxy.name 操作时,由于 Person 已被 Proxy 代理,任何通过该 Proxy 实例访问 Person 中已存在属性的行为,都会触发 get 方法,从而实现对属性读取的拦截。

在 get: function (target, property) 中,target 和 property 两个参数分别接收目标对象和属性名,具体数据流向如图所示

什么是代理模式

通过代理对象访问 Person 中已存在的属性不会报错,但如果访问不存在的属性会发生什么?

什么是代理模式

究竟是什么机制导致访问不存在的属性时抛出异常?

这是因为外部对 Person 对象的访问必须经过 Proxy 设置的拦截层,该拦截层提供了过滤和改写访问请求的机制。


// 判断外界访问的对象属性是否存在于目标对象中。
if (property in target) {
    return target[property];
} else {
    // 如果外界访问的对象属性不存在与目标对象中,抛出异常。
    throw new ReferenceError('Property "' + property + '" 不存在。');
}

代码中的 if 语句构成了拦截层的具体逻辑,即对访问请求进行过滤和改写。若缺少此判断,访问不存在的属性将直接返回 undefined。

什么是代理模式

set(target, propKey, value, receiver)

继续使用 Person 对象,此时新增需求:修改 age 属性时,要求值必须为整数且不超过 150。

在 Proxy 对象中新增 set 方法以处理赋值逻辑。


var proxy = new Proxy(person, {
    set: function (target, property, value) {
          // 打印target、property和value,查看里面到底是什么。
          console.log("target = ", target);
          console.log("property = ", property);
          console.log("value = ", value);
          if (property === "age") {
                if (!Number.isInteger(value)) {
                  throw new TypeError("age的值不是整数!");
                }
                if (value > 150) {
                  throw new RangeError("age的值不能大于150!");
                }
          }
    },
});

当执行 proxy.age = 100 时,set 方法的三个参数分别接收目标对象、属性名和赋值,具体数据如图所示。

什么是代理模式

set 方法用于拦截属性赋值操作,如果 age 的赋值不满足预设条件,将会发生什么?

什么是代理模式

显然,程序会抛出异常以阻止非法赋值。

总结

Proxy 本质上是一个拦截层。用户传入目标对象,外部对该对象的访问必须经过 Proxy 实例。通过 Proxy 可实现对访问行为的过滤和改写,例如在赋值时强制满足特定条件。

Proxy 对象还包含 has、deleteProperty、ownKeys、getOwnPropertyDescriptor 等其他拦截方法,用于处理不同的拦截场景。

以上就是 js Proxy 的原理详解的详细内容,更多关于 js Proxy 的资料请关注本站其它相关文章!

作者最新文章