外观
代理模式在前端哪里见过?
代理和真实对象提供同样的使用方式,由代理控制访问:延迟创建、做缓存、加权限或记录日志。ES6 的 Proxy 是语言级的拦截,代理模式是这个思路,不一定用那个 API。
原理
图片还没进入视口时,页面拿着一个占位对象;真正进入视口再加载图片。调用方始终叫的是「显示这张图」。这是虚拟代理。
缓存代理包住昂贵的计算函数,参数相同就返回上次的结果。见 函数缓存。
保护代理在操作前检查权限,失败就拒绝,不把检查散落在每个按钮里。前端检查只改善体验。见 权限控制。
Vue 的响应式对象是访问代理:读的时候登记依赖,写的时候通知。调用方以为自己在改普通对象。见 Vue 响应式。
代理不该改变业务含义。如果调用方必须知道背后换了实现,那就是另一个接口,不是代理。
追问
和装饰器的差别?
代理强调自己代替原对象被使用,调用方可以只依赖代理。装饰器更常指在编译或定义时给类、方法附加行为。都能「包一层」,意图不同。见 装饰器。
和适配器呢?
适配器把一个不合用的接口改成调用方要的接口。代理保持接口不变,增加控制。
易错点
- 把所有中间层都叫代理。改了方法签名的是适配或封装。
- 代理里做重逻辑,真实对象反而很薄,职责反了。
Proxy没转发的操作会丢,例如没实现ownKeys时枚举和原对象不一致。