广州网站订制开发,泉州企业建站模板,某网站做参考文献的书写,松江品牌网站建设先理解 Proxy 的核心思想
Proxy 就像一个“拦截器”#xff0c;它可以“监听”一个对象的操作#xff0c;比如#xff1a;
访问对象的属性#xff08;读取#xff09; → 触发 get 拦截器给对象的属性赋值#xff08;写入#xff09; → 触发 set 拦截器调用对象的方法…先理解 Proxy 的核心思想Proxy 就像一个“拦截器”它可以“监听”一个对象的操作比如访问对象的属性读取 → 触发get拦截器给对象的属性赋值写入 → 触发set拦截器调用对象的方法 → 其实是先访问方法触发get再执行它但集合类型Map、Set 等不直接用属性赋值来写入数据Map 写入数据是调用它的set(key, value)方法Set 写入数据是调用它的add(value)方法读取数据是调用 Map 的get(key)或 Set 的has(value)方法所以我们想拦截“写入”操作就要拦截这些方法的调用。Proxy 怎么拦截方法调用当你访问proxyMap.set会触发 Proxy 的get拦截器告诉你访问了set方法。这时我们返回一个“包装函数”这个函数内部可以插入自定义逻辑比如打印日志然后再调用原始的set方法。这样就实现了“拦截写入操作”。具体示例拦截 Map 的读取和写入constmapnewMap();consthandler{get(target,prop,receiver){// 访问属性或方法时触发constorigMethodtarget[prop];if(typeoforigMethodfunction){// 如果访问的是方法返回一个包装函数returnfunction(...args){if(propset){console.log(写入操作set(${args[0]},${args[1]}));}elseif(propget){console.log(读取操作get(${args[0]}));}// 调用原始方法returnorigMethod.apply(target,args);};}// 访问普通属性直接返回returnReflect.get(target,prop,receiver);}};constproxyMapnewProxy(map,handler);proxyMap.set(name,CodeMoss);// 控制台输出写入操作set(name, CodeMoss)console.log(proxyMap.get(name));// 控制台输出读取操作get(name)// 输出CodeMoss可以把它理解成访问proxyMap.set→ Proxy 拦截返回一个“带日志”的函数调用这个函数时先打印日志再调用真正的map.setSet 也是类似的只是写入方法叫add读取方法叫hasconstsetnewSet();consthandler{get(target,prop,receiver){constorigMethodtarget[prop];if(typeoforigMethodfunction){returnfunction(...args){if(propadd){console.log(写入操作add(${args[0]}));}elseif(prophas){console.log(读取操作has(${args[0]}));}returnorigMethod.apply(target,args);};}returnReflect.get(target,prop,receiver);}};constproxySetnewProxy(set,handler);proxySet.add(123);// 控制台输出写入操作add(123)console.log(proxySet.has(123));// 控制台输出读取操作has(123)// 输出trueWeakMap 和 WeakSet 也一样只是它们的键或值必须是对象且不能遍历constweakMapnewWeakMap();consthandler{get(target,prop,receiver){constorigMethodtarget[prop];if(typeoforigMethodfunction){returnfunction(...args){if(propset){console.log(WeakMap 写入操作键:,args[0],值:,args[1]);}elseif(propget){console.log(WeakMap 读取操作键:,args[0]);}returnorigMethod.apply(target,args);};}returnReflect.get(target,prop,receiver);}};constproxyWeakMapnewProxy(weakMap,handler);constobjKey{};proxyWeakMap.set(objKey,secret);// 控制台输出WeakMap 写入操作键: {} 值: secretconsole.log(proxyWeakMap.get(objKey));// 控制台输出WeakMap 读取操作键: {}// 输出secret总结Proxy 的get拦截器拦截的是“属性访问”方法调用是先访问方法再执行。集合的写入和读取都是通过调用方法实现的所以我们拦截方法访问返回包装函数。包装函数里可以插入自定义逻辑日志、权限等然后调用原始方法完成操作。把 const objKey {}; 换成 map”把 WeakMap 的键从一个普通对象{}换成一个 Map 对象。先说明一点WeakMap 的键必须是对象而 Map 本身是一个对象它是一个构造函数实例所以理论上是可以作为 WeakMap 的键的。可以这样写constweakMapnewWeakMap();consthandler{get(target,prop,receiver){constorigMethodtarget[prop];if(typeoforigMethodfunction){returnfunction(...args){if(propset){console.log(WeakMap 写入操作键:,args[0],值:,args[1]);}elseif(propget){console.log(WeakMap 读取操作键:,args[0]);}returnorigMethod.apply(target,args);};}returnReflect.get(target,prop,receiver);}};constproxyWeakMapnewProxy(weakMap,handler);// 这里用 Map 作为键constmapKeynewMap();proxyWeakMap.set(mapKey,secret);// 控制台输出WeakMap 写入操作键: Map {} 值: secretconsole.log(proxyWeakMap.get(mapKey));// 控制台输出WeakMap 读取操作键: Map {}// 输出secret解释mapKey是一个 Map 实例属于对象类型可以作为 WeakMap 的键。WeakMap 允许任何对象作为键包括普通对象、数组、函数、甚至 Map、Set 等实例。用 Map 作为键完全没问题。