【ES6新特性】Proxy进阶实战

🌟ES6 Proxy终极指南:从拦截器到响应式框架实现🔥

在这里插入图片描述


一、💡 为什么Proxy是革命性的?先看痛点场景

1.1 Object.defineProperty的局限 😫

// Vue2响应式实现
let data = { count: 0 };
Object.defineProperty(data, 'count', {get() { /* 依赖收集 */ },set() { /* 触发更新 */ }
});// 痛点:
// 1. 无法检测数组变化
// 2. 需要递归遍历对象
// 3. 无法拦截属性的新增/删除
data.arr.push(1); // 不会触发更新

1.2 Proxy的三大降维打击优势 🔥

  1. 全拦截能力:13种对象操作拦截
  2. 非侵入式监控:无需修改原对象
  3. 性能优化空间:懒代理+缓存策略

二、🚀 Proxy核心API完全解析

2.1 基础语法与拦截器全集 📚

const handler = {// 🔥 核心拦截操作(部分)get(target, prop) { /* 属性读取 */ },set(target, prop, value) { /* 属性设置 */ },apply(target, thisArg, args) { /* 函数调用 */ },construct(target, args) { /* new操作 */ },has(target, prop) { /* in操作符 */ },deleteProperty(target, prop) { /* delete操作 */ }
};const proxy = new Proxy(target, handler);

2.2 与Reflect的黄金组合 💎

Proxy陷阱Reflect方法说明
getReflect.get保持默认行为
setReflect.set返回操作结果布尔值
applyReflect.apply保持函数执行上下文
constructReflect.construct正确维护new.target

正确用法示例

const handler = {get(target, prop, receiver) {console.log(`Getting ${prop}`);return Reflect.get(...arguments);}
};

三、💎 五大框架级实战场景

3.1 场景1:实现Vue3响应式系统 🚀

const reactiveMap = new WeakMap();function reactive(obj) {const proxy = new Proxy(obj, {get(target, key, receiver) {track(target, key); // 依赖收集return Reflect.get(...arguments);},set(target, key, value, receiver) {const result = Reflect.set(...arguments);trigger(target, key); // 触发更新return result;}});reactiveMap.set(obj, proxy);return proxy;
}// 使用
const state = reactive({ count: 0 });
state.count++; // 自动触发更新

3.2 场景2:实现ORM层查询拦截 ✨

const database = {users: [{ id: 1, name: 'Alice', age: 25 }]
};const dbProxy = new Proxy(database, {get(target, prop) {if (prop === 'findUser') {return (id) => target.users.find(u => u.id === id);}return Reflect.get(...arguments);}
});console.log(dbProxy.findUser(1)); // 自动创建查询方法

3.3 场景3:实现API请求拦截器 🌐

const apiHandler = {get(target, prop) {return (...args) => {const [params] = args;console.log(`Calling ${prop} with`, params);return fetch(`/api/${prop}`, { body: JSON.stringify(params) });};}
};const api = new Proxy({}, apiHandler);// 使用
api.getUser({ id: 1 }); // 自动生成接口调用

四、⚡ 高级模式与性能优化

4.1 递归代理实现 🧠

function deepProxy(obj, handler) {if (typeof obj === 'object' && obj !== null) {for (let key in obj) {obj[key] = deepProxy(obj[key], handler);}return new Proxy(obj, handler);}return obj;
}const state = deepProxy({ user: { name: 'Bob',address: { city: 'Beijing' }}
}, {set(target, prop, value) {console.log('Deep set:', prop);return Reflect.set(...arguments);}
});state.user.address.city = 'Shanghai'; // 触发日志

4.2 性能压测与优化策略 📊

// 创建10万属性的对象
const data = Array(1e5).fill(0).reduce((acc, _, i) => {acc[i] = i;return acc;
}, {});// 普通访问
console.time('Raw access');
data[50000]; 
console.timeEnd('Raw access'); // ~0.01ms// Proxy访问
const proxy = new Proxy(data, {});
console.time('Proxy access');
proxy[50000];
console.timeEnd('Proxy access'); // ~0.03ms// 优化方案:缓存常用属性访问
const cacheHandler = {get(target, prop) {if (prop === 'cachedProp') {return target[prop] ||= computeExpensiveValue();}return Reflect.get(...arguments);}
};

五、📌 高频面试题精选

Q1:Proxy与Object.defineProperty的区别?

💡 深度解析

特性ProxyObject.defineProperty
拦截范围13种操作仅get/set
数组处理完美支持需要hack处理
属性监听全属性自动监听需显式定义每个属性
性能影响轻微大量属性时较差

Q2:如何实现撤销代理?

const { proxy, revoke } = Proxy.revocable({}, {get(target, prop) {return `Accessing ${prop}`;}
});console.log(proxy.name); // Accessing name
revoke();
console.log(proxy.name); // TypeError: Cannot perform 'get' on a proxy that has been revoked

六、🌈 总结与最佳实践

🚦 Proxy使用决策矩阵

场景推荐方案
数据响应式Proxy + 依赖跟踪
API网关方法拦截自动生成
权限控制操作前校验拦截
日志/性能监控透明化行为记录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/76874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++解决动态规划

一、引言: 在我们学习了算法之后,我们一定遇到过贪心算法。而在贪心算法中就有着这样一个经典的例子——凑钱。 Eg: 你有面额为10、5、1的纸币,当你买菜时需要花费26元,请问需要最少的纸币张数是多少。 当我们用贪心算法去解决这个问题的时候,我们…

Qwen 2.5 VL 多种推理方案

Qwen 2.5 VL 多种推理方案 flyfish 单图推理 from modelscope import Qwen2_5_VLForConditionalGeneration, AutoTokenizer, AutoProcessor from qwen_vl_utils import process_vision_info import torchmodel_path "/media/model/Qwen/Qwen25-VL-7B-Instruct/"m…

机器视觉检测Pin针歪斜应用

在现代电子制造业中,Pin针(插针)是连接器、芯片插座、PCB板等元器件的关键部件。如果Pin针歪斜,可能导致接触不良、短路,甚至整机失效。传统的人工检测不仅效率低,还容易疲劳漏检。 MasterAlign 机器视觉对…

经典算法问题解析:两数之和与三数之和的Java实现

文章目录 1. 问题背景2. 两数之和(Two Sum)2.1 问题描述2.2 哈希表解法代码实现关键点解析复杂度对比 3. 三数之和(3Sum)3.1 问题描述3.2 排序双指针解法代码实现关键点解析复杂度分析 4. 对比总结5. 常见问题解答6. 扩展练习 1. …

1022 Digital Library

1022 Digital Library 分数 30 全屏浏览 切换布局 作者 CHEN, Yue 单位 浙江大学 A Digital Library contains millions of books, stored according to their titles, authors, key words of their abstracts, publishers, and published years. Each book is assigned an u…

地理人工智能中位置编码的综述:方法与应用

以下是对论文 《A Review of Location Encoding for GeoAI: Methods and Applications》 的大纲和摘要整理: A Review of Location Encoding for GeoAI: Methods and Applications 摘要(Summary) 本文系统综述了地理人工智能(G…

(C语言)算法复习总结2——分治算法

1. 分治算法的定义 分治算法(Divide and Conquer)是一种重要的算法设计策略。 “分治” 从字面意义上理解,就是 “分而治之”。 它将一个复杂的问题分解成若干个规模较小、相互独立且与原问题形式相同的子问题,然后递归地解决这…

爱普生FC1610AN5G手机中替代传统晶振的理想之选

在 5G 技术引领的通信新时代,手机性能面临前所未有的挑战与机遇。从高速数据传输到多任务高效处理,从长时间续航到紧凑轻薄设计,每一项提升都离不开内部精密组件的协同优化。晶振,作为为手机各系统提供稳定时钟信号的关键元件&…

Android 接口定义语言 (AIDL)

目录 1. 本地进程调用(同一进程内)2. 远程进程调用(跨进程)3 `oneway` 关键字用于修改远程调用的行为Android 接口定义语言 (AIDL) 与其他 IDL 类似: 你可以利用它定义客户端与服务均认可的编程接口,以便二者使用进程间通信 (IPC) 进行相互通信。 在 Android 上,一个进…

关于QT5项目只生成一个CmakeLists.txt文件

编译器自动检测明明可以检测,Kit也没有报红 但是最后生成项目只有一个文件 一:检查cmake版本,我4.1版本cmake一直报错 cmake3.10可以用 解决之后还是有问题 把环境变量加上去:

uniapp小程序位置授权弹框与隐私协议耦合(合而为一)(只在真机上有用,模拟器会分开弹 )

注意: 只在真机上有用,模拟器会分开弹 效果图: 模拟器效果图(授权框跟隐私政策会分开弹,先弹隐私政策,同意再弹授权弹框): manifest-template.json配置( "__usePr…

[Godot] C#人物移动抖动解决方案

在写一个2D平台跳跃的游戏代码发现,移动的时候会抖动卡顿的厉害,后来研究了一下抖动问题,有了几种解决方案 1.垂直同步和物理插值问题 这是最常见的可能导致画面撕裂和抖动的原因,大家可以根据自己的需要调整项目设置&#xff0…

红帽Linux网页访问问题

配置网络,手动配置 搭建yum仓库红帽Linux网页访问问题 下载httpd 网页访问问题:首先看httpd的状态---selinux的工作模式(强制)---上下文类型(semanage-fcontext)---selinux端口有没有放行semanage port ---防火墙有没有active---…

Android12编译x86模拟器报找不到userdata-qemu.img

qemu-system-x86_64: Could not open out/target/product/generic_x86_64/userdata-qemu.img: No such file or directory 选择编译aosp_x86-eng时没有生成模拟器,报 qemu-system-x86_64: Could not open out/target/product/generic_x86_64/userdata-qemu.img: No…

【AI论文】PixelFlow:基于流的像素空间生成模型

摘要:我们提出PixelFlow,这是一系列直接在原始像素空间中运行的图像生成模型,与主流的潜在空间模型形成对比。这种方法通过消除对预训练变分自编码器(VAE)的需求,并使整个模型能够端到端训练,从…

AI大模型学习九:‌Sealos cloud+k8s云操作系统私有化一键安装脚本部署完美教程(单节点)

一、说明 ‌Sealos‌是一款基于Kubernetes(K8s)的云操作系统发行版,它将K8s以及常见的分布式应用如Docker、Dashboard、Ingress等进行了集成和封装,使得用户可以在不深入了解复杂的K8s底层原理的情况下,快速搭建起一个…

【HDFS入门】HDFS核心组件DataNode详解:角色职责、存储机制与健康管理

目录 1 DataNode的角色定位 2 DataNode的核心职责 2.1 数据块管理 2.2 与NameNode的协作 3 DataNode的存储机制 3.1 数据存储目录结构 3.2 数据块文件组织 4 DataNode的工作流程 4.1 数据写入流程 4.2 数据读取流程 5 DataNode的健康管理 5.1 心跳机制(…

BufferedOutputStream 终极解析与记忆指南

BufferedOutputStream 终极解析与记忆指南 一、核心本质 BufferedOutputStream 是 Java 提供的缓冲字节输出流,继承自 FilterOutputStream,通过内存缓冲区显著提升 I/O 性能。 核心特性速查表 特性说明继承链OutputStream → FilterOutputStream → …

光纤模块全解:深入了解XFP、SFP、QSFP28等类型

随着信息技术的快速发展,数据中心和网络的带宽需求不断提高,光纤模块的选择与应用显得尤为重要。光纤模块是实现高速网络连接的重要组件,选择合适的模块能够显著提升传输性能、降低延迟。本文将深入解析几种常见的光纤模块类型,包…

【高阶数据结构】第三弹---图的存储与遍历详解:邻接表构建与邻接矩阵的BFS/DFS实现

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【高阶数据结构】 目录 1、图的存储结构 1.1、邻接表 1.1.1、边的结构 1.1.2、图的基本结构 1.1.3、图的创建 1.1.4、获取顶点下…