1. Definition
Proxy pattern: Provide a surrogate or placeholder for an object in order to control access to it.
Agents are divided into: Protection agents and virtual agents
Protection agent: is used to control the access of objects with different permissions to the target object. It is difficult to judge who has accessed an object in JavaScript, so the protection agent is difficult to implement.
2. Image preloading (the most common virtual agent application scenario)
Image preloading is a common technology. If you directly set the src attribute for an img tag node, the image position will often be blank for a period of time due to the image being too large or the network being poor. A common approach is to use a loading image as a placeholder in advance, and then load the image asynchronously. After the image is loaded, fill it into the img node.
Implementation principle:
Create an Image object: var a = new Image();
Define the src of the Image object: a.src = “xxx.gif”;
Doing so is equivalent to caching an image for the browser.
You can check whether the image is loaded through the complete attribute of the Image object. Each Image object has a complete attribute. When the image is in the loading process, the attribute value is false. When any of the onload, onerror, and onabort events occurs, it means that the image loading process is over. At this time, the complete attribute is true. .
(1) Non-proxy implementation
var myImage = (function() { var imgNode = document.createElement("img"); document.body.appendChild(imgNode); var img = new Image(); img.onload = function() { imgNode.src = img.src; }; return { setSrc: function(src) { imgNode.src = "./images/loading.gif"; img.src = src; } } })(); myImage.setSrc("./images/originImg.png");
(2) Proxy implementation
// 创建图片DOM var myImage = (function() { var imgNode = document.createElement("img"); document.body.appendChild(imgNode); return { setSrc: function(src) { imgNode.src = src; } }; })(); // 代理 var proxyImage = (function() { var img = new Image(); img.onload = function() { myImage.setSrc(this.src); // this指向img!img加载完成后,将img.src传递给myImage }; return { setSrc: function(src) { myImage.setSrc("./images/loading.gif"); // loading img.src = src; } }; })(); proxyImage.setSrc("./images/originImg.png");
The benefits of using the proxy mode: making each function single-function and realizing the "single responsibility principle" of object design!
3. File synchronization
Suppose we are doing a file synchronization function. When the checkbox is selected, its corresponding file will be synchronized to another server.
<body> <input type="checkbox" id="1" />文件1 <input type="checkbox" id="2" />文件2 <input type="checkbox" id="3" />文件3 <input type="checkbox" id="4" />文件4 <input type="checkbox" id="5" />文件5 <input type="checkbox" id="6" />文件6 </body>
It is obviously unreasonable to synchronize once without selecting a checkbox. Because in web development, the biggest overhead is network requests.
Solution: Use a proxy function to collect requests within a period of time, and then send them to the server all at once.
var synchronousFile = function(id) { console.log("开始同步文件,id为:" + id); }; var proxySynchonousFile = (function() { var cache = [], // 保存本次需要同步文件的id timer; // 定时器 return function(id) { cache.push(id); if(timer) { // 不要覆盖已经启动的定时 return; } timer = setTimeout(function(){ synchronousFile(cache.join(",")); clearTimeout(timer); timer = null; cache.length = 0; // 清空缓存 }, 2000); } })(); var checkboxs = document.getElementsByTagName("input"); for(var i = 0, c; c = checkboxs[i]; i++) { c.onclick = function() { if(this.checked === true) { proxySynchonousFile(this.id); } } }
4. Caching proxy – calculating the product (the sequence is exactly the same)
var mult = function() { var result = 1; for(var i = 0, l = arguments.length; i < l; i++) { result= result * arguments[i]; } return result; }; var proxyMult = (function() { var cache = {}; // {"1,2,3": 6} return function() { var args = Array.prototype.join.call(arguments, ","); if(args in cache) { return cache[args]; } return cache[args] = mult.apply(this, arguments); } })(); console.log(proxyMult(1, 2, 3)); // 改造: var proxyFactory = function(fn) { var cache = {}; return function() { var args = Array.prototype.join.call(arguments, ","); if(args in cache) { return cache[args]; } return cache[args] = fn.apply(this, arguments); } }; console.log(proxyFactory(mult)(1, 2, 3));
I hope this article will be helpful to everyone learning JavaScript programming.