导读:本期聚焦于小伙伴创作的《JavaScript代理模式如何实现拦截器与验证器实战应用》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript代理模式如何实现拦截器与验证器实战应用》有用,将其分享出去将是对创作者最好的鼓励。

JavaScript的代理模式依托于内置的Proxy对象实现,允许开发者创建一个对象的代理,从而拦截并重新定义该对象的基本操作,比如属性读取、赋值、函数调用等。这种模式非常适合用来实现统一的拦截逻辑和数据验证规则,无需修改原对象的代码就能扩展功能。

JavaScript代理模式如何实现拦截器与验证器实战应用

代理模式核心概念

Proxy对象接收两个参数,第一个是被代理的目标对象,第二个是处理器对象,处理器对象中包含各种捕获器,用来拦截对应的操作。常见的捕获器包括get用于拦截属性读取,set用于拦截属性赋值,has用于拦截in操作符等。

基础的使用示例如下:

// 目标对象
const target = {
  name: '张三',
  age: 20
};

// 处理器对象,定义拦截规则
const handler = {
  get(target, prop, receiver) {
    console.log(`读取属性 ${prop}`);
    return Reflect.get(target, prop, receiver);
  },
  set(target, prop, value, receiver) {
    console.log(`设置属性 ${prop} 为 ${value}`);
    return Reflect.set(target, prop, value, receiver);
  }
};

// 创建代理对象
const proxy = new Proxy(target, handler);

// 触发get捕获器
console.log(proxy.name); // 输出:读取属性 name 张三
// 触发set捕获器
proxy.age = 21; // 输出:设置属性 age 为 21

拦截器实战应用

拦截器可以在对象操作执行前后插入自定义逻辑,比如操作日志记录、权限校验、数据格式化等。下面实现一个接口请求参数的拦截器,在发送请求前统一处理参数格式。

// 请求参数目标对象
const requestParams = {
  userId: 1001,
  userName: '李四'
};

// 拦截器处理器
const requestInterceptor = {
  set(target, prop, value) {
    // 拦截赋值操作,自动去除字符串首尾空格
    if (typeof value === 'string') {
      value = value.trim();
    }
    // 记录参数修改日志
    console.log(`请求参数 ${prop} 被修改为 ${value}`);
    target[prop] = value;
    return true;
  },
  get(target, prop) {
    // 拦截读取操作,添加参数来源标记
    const value = target[prop];
    if (value !== undefined) {
      return `【请求参数】${value}`;
    }
    return undefined;
  }
};

const proxyParams = new Proxy(requestParams, requestInterceptor);

// 测试拦截器效果
proxyParams.userName = ' 王五 '; // 输出:请求参数 userName 被修改为 王五
console.log(proxyParams.userName); // 输出:【请求参数】王五
console.log(proxyParams.userId); // 输出:【请求参数】1001

验证器实战应用

验证器可以在对象属性赋值时校验数据的合法性,不符合规则的数据直接拒绝赋值并抛出提示,避免非法数据流入后续逻辑。下面实现一个用户信息的验证器,校验年龄和邮箱格式。

// 用户信息目标对象
const userInfo = {
  age: 0,
  email: ''
};

// 验证器处理器
const validator = {
  set(target, prop, value) {
    if (prop === 'age') {
      // 校验年龄必须是1-120之间的整数
      if (!Number.isInteger(value) || value < 1 || value > 120) {
        throw new Error('年龄必须是1到120之间的整数');
      }
    }
    if (prop === 'email') {
      // 简单校验邮箱格式
      const emailReg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/;
      if (!emailReg.test(value)) {
        throw new Error('邮箱格式不正确');
      }
    }
    target[prop] = value;
    return true;
  }
};

const proxyUser = new Proxy(userInfo, validator);

// 测试验证器效果
try {
  proxyUser.age = 25; // 合法赋值
  proxyUser.email = 'test@ipipp.com'; // 合法赋值
  console.log('用户信息赋值成功');
} catch (e) {
  console.log(e.message);
}

try {
  proxyUser.age = 150; // 非法赋值,触发错误
} catch (e) {
  console.log(e.message); // 输出:年龄必须是1到120之间的整数
}

try {
  proxyUser.email = 'invalid-email'; // 非法赋值,触发错误
} catch (e) {
  console.log(e.message); // 输出:邮箱格式不正确
}

拦截器与验证器结合使用

实际开发中可以将拦截器和验证器的逻辑结合,既做数据校验又做操作记录,提升代码的复用性。下面的案例将之前的拦截和验证逻辑合并到一个处理器中。

const product = {
  price: 0,
  stock: 0
};

const productHandler = {
  get(target, prop) {
    console.log(`读取商品属性 ${prop}`);
    return target[prop];
  },
  set(target, prop, value) {
    // 先执行验证逻辑
    if (prop === 'price') {
      if (typeof value !== 'number' || value < 0) {
        throw new Error('商品价格必须是大于等于0的数字');
      }
    }
    if (prop === 'stock') {
      if (!Number.isInteger(value) || value < 0) {
        throw new Error('商品库存必须是大于等于0的整数');
      }
    }
    // 再执行拦截记录逻辑
    console.log(`商品 ${prop} 被设置为 ${value}`);
    target[prop] = value;
    return true;
  }
};

const proxyProduct = new Proxy(product, productHandler);

// 测试组合效果
proxyProduct.price = 99.9; // 输出:商品 price 被设置为 99.9
proxyProduct.stock = 100; // 输出:商品 stock 被设置为 100
console.log(proxyProduct.price); // 输出:读取商品属性 price 99.9

try {
  proxyProduct.price = -10; // 触发验证错误
} catch (e) {
  console.log(e.message); // 输出:商品价格必须是大于等于0的数字
}

注意事项

  • Proxy代理的是对象本身,修改代理对象的属性会同步影响目标对象,除非在捕获器中手动阻止。
  • 捕获器中尽量使用Reflect对应的方法执行默认操作,保证行为的一致性和正确性。
  • 代理模式会增加一定的性能开销,不要在高频操作的场景下过度使用。
  • 代理对象没有prototype属性,无法通过instanceof判断和目标对象的关系。

JavaScript代理模式拦截器验证器Proxy修改时间:2026-07-06 06:48:24

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。