代理模式
定义:为一个对象提供一个代用品或占位符,以便控制对它的访问。
代理对象和本体对象实现了同样的接口,并且会把任何方法调用传递给本体对象;
举例:
图片预加载、图片懒加载、
合并HTTP请求(代理收集一定时间内的所有HTTP请求,然后一次性发给服务器)、
惰性加载(通过代理处理和收集一些基本操作,然后仅在真正需要本体的时候才加载本体)、
缓存代理(缓存请求结果、计算结果)
缓存代理
const mult = function() { let a = 1; for (let i = 0; i < arguments.length; i++) { a *= arguments[i]; } return a; }; const plus = function() { let a = 0; for (let i = 0; i < arguments.length; i++) { a += arguments[i]; } return a; };
const createProxyFactory = function(fn) { let cache = {}; return function() { let args = Array.from(arguments).join(','); if (args in cache) { return cache[args]; } else { return cache[args] = fn.apply(this, arguments); } }; };
const proxyMult = createProxyFactory(mult); const proxyPlus = createProxyFactory(plus); console.log(proxyMult(1,2,3,4)); console.log(proxyPlus(1,2,3,4));
|
说明:这里每次进行同类的计算时(乘法和加法两类),先判断缓存对象cache中是否存在该参数连接成的字符串作为key的属性。如果有,则直接从cache中读取,否则就进行计算并保存其结果。
虚拟代理
const imgFunc = (function() { const imgNode = document.createElement('img'); document.body.appendChild(imgNode); return { setSrc(src){ imgNode.src = src; } } })();
const proxyImage = (function() { const img = new Image(); img.onload = function() { imgFunc.setSrc(this.src); }; return { setSrc(src){ imgFunc.setSrc('./loading.gif'); img.src = src; } }; })();
proxyImage.setSrc('./reality.png');
|
说明:图片懒加载的方式:先通过一张loading图占位,然后通过异步的方式加载图片,等图片加载好了再把完成的图片加载到img标签里面。这里讲述一下代理对象做了那些事:
1.创建了一个 Image 对象,并为其绑定了 onload 事件。
2.将 imgNode 先设置为 ‘./loading.gif’ 加载的菊花图。
3.当 Image 对象加载完真实的图片,也就是上文的 ‘./reality.png’ ,将 imgNode 设置为 ‘./reality.png’。
参考文档:
js设计模式(9)—代理模式
JavaScript设计模式
js用高阶函数动态创建缓存代理
- end -