当前位置: 首页 > news >正文

JavaScript:Proxy 代理

Proxy 的基本概念

ES6 引入的 Proxy 用于创建一个对象的代理,从而可以拦截和自定义对象的底层操作。Proxy 提供了一种机制,允许在访问或修改对象时添加自定义行为。

Proxy 的语法

const proxy = new Proxy(target, handler);
  • target:需要被代理的目标对象。
  • handler:一个对象,包含拦截操作的“陷阱”(trap)方法。

常见的陷阱方法

  • get(对象, 对象的某个属性, receiver):拦截对象属性的读取操作。
  • set(对象, 对象的某个属性, 给该对象这个属性赋的新值, receiver):拦截对象属性的设置操作。
  • has(target, prop):拦截 in 操作符。
  • deleteProperty(target, prop):拦截 delete 操作。
  • apply(target, thisArg, args):拦截函数调用。
  • construct(target, args, newTarget):拦截 new 操作符。

一般主要用的就是 getset

示例代码

拦截属性读取和设置
const target = { name: "Alice", age: 25 };
const handler = {get(target, prop) {console.log(`Reading property: ${prop}`);return target[prop];},set(target, prop, value) {console.log(`Setting property: ${prop} to ${value}`);target[prop] = value;return true; // 表示操作成功}
};
const proxy = new Proxy(target, handler);console.log(proxy.name); // 输出: Reading property: name  Alice
proxy.age = 30; // 输出: Setting property: age to 30

Proxy 的用途

  • 数据验证:在设置属性时验证值的合法性。
  • 日志记录:跟踪对象的访问和修改。
  • 性能优化:延迟加载或缓存计算结果。
  • 实现私有属性:通过拦截访问隐藏某些属性。

注意事项

  • Proxy 的陷阱方法是可选的,未定义的陷阱会直接转发到目标对象。
  • Proxy 无法拦截一些底层操作,例如 Object.keysfor...in 循环。
  • 使用 Proxy 可能会带来一定的性能开销,需谨慎在高性能要求的场景中使用。

defineProperty 和 Proxy

Vue2 使用 Object.defineProperty 来实现数据响应式。这种方式通过劫持对象的属性访问和修改来实现数据监听

const data = { name: 'Vue' };
Object.defineProperty(data, 'name', {get() {console.log('触发 getter');return this._name;},set(newVal) {console.log('触发 setter');this._name = newVal;}
});

Vue2 是针对属性的监听,所以它必须去深度遍历对象里的每个属性,才能进行监听(把每个属性的读取和赋值变成函数)
这样的话缺陷就很明显了,深度遍历会导致效率上的损失,并且无法监听属性的新增和删除

Vue3 进行改进,它是监听整个对象,只要对这个对象进行操作,就会收到通知。由于现在不监听属性了,所以不用去遍历了

const data = { name: 'Vue' };
const proxy = new Proxy(data, {get(target, key) {console.log('触发 getter');return target[key];},set(target, key, value) {console.log('触发 setter');target[key] = value;return true;}
});

在上面代码中,我们后续都是通过操作代理对象 proxy 来改变 data

http://www.dtcms.com/a/316323.html

相关文章:

  • 【数据结构初阶】--排序(三):冒泡排序,快速排序
  • 编码器模型和解码器模型解析
  • MongoDB学习专题(一)介绍安装基本操作
  • ✨OpenVoice 全流程实战:多语言语音合成系统安装与使用教程(附踩坑经验)
  • Makefile工具、双向链表
  • xshell、xftp使用案例
  • 【2025年8月5日】将运行一段时间的单机MongoDB平滑迁移至副本集集群
  • java回顾八股文中想起的知识点
  • 为什么不用rocketmq直接发送,用StreamBridge
  • 使用Playwright MCP探索网站并编写测试
  • 解锁n8n:开启自动化工作流的无限可能
  • 面试题:vue3使用proxy相较于vue2的优点在哪里
  • 03-基于深度学习的钢铁缺陷检测-yolo11-彩色版界面
  • postman接口测试实战
  • 鸿蒙组件装饰器深度解析:@Component vs @ComponentV2
  • 【实时Linux实战系列】基于实时Linux的智能交通系统设计
  • 数据结构---Makefile 文件(格式、文件变量、调用、伪目标)、gcc编译的四个步骤、双向链表(概念、作用、应用)
  • 若依vue前端处理日期数据的格式问题(只留下年月日,去掉时分秒)
  • 小易的yolo学习笔记2
  • AlexNet训练和测试FashionMNIST数据集
  • 系统启动项管理工具对美国服务器性能基线的验证标准
  • Rust进阶-part4-智能指针2
  • 真正的多模态上下文学习需要关注视觉上下文
  • 人工智能领域、图欧科技、IMYAI智能助手2025年1月更新月报
  • 【RabbitMQ】高级特性—消息确认详解
  • 轻量应用服务器Centos系统上安装jdk8和Jdk17教程(详细)
  • BFS 和 DFS 编程思想、框架、技巧及经典例题总结
  • 【Git学习】入门与基础
  • 达芬奇31-40
  • Java技术栈/面试题合集(8)-Redis篇