新聞中心
這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
JavaScript設(shè)計(jì)模式之代理模式詳解
代理模式是非常常見的模式,比如我們使用的VPN工具,明星的經(jīng)紀(jì)人,都是代理模式的例子。但是,有人會(huì)疑問,明明可以直接訪問對(duì)象,為什么中間還要加一個(gè)殼呢?這也就說到了代理模式的好處。在我看來,代理模式最大的好處,就是在不動(dòng)原有對(duì)象的同時(shí),可以給原有對(duì)象增加一些新的特性或者行為。
成都創(chuàng)新互聯(lián)是一家專業(yè)從事成都做網(wǎng)站、成都網(wǎng)站制作的網(wǎng)絡(luò)公司。作為專業(yè)網(wǎng)站設(shè)計(jì)公司,成都創(chuàng)新互聯(lián)依托的技術(shù)實(shí)力、以及多年的網(wǎng)站運(yùn)營(yíng)經(jīng)驗(yàn),為您提供專業(yè)的成都網(wǎng)站建設(shè)、成都營(yíng)銷網(wǎng)站建設(shè)及網(wǎng)站設(shè)計(jì)開發(fā)服務(wù)!
/** * pre:代理模式 * 小明追求A,B是A的好朋友,小明比較靦腆,不好意思直接將花交給A, * 于是小明將花交給B,再由B交給A. */ //----------- 示例1 --------- // 不使用代理 var Flower = function() {}; var xiaoming = { sendFlower: function(target) { var flower = new Flower(); target.receiveFlower(flower); } }; var A = { receiveFlower: function(flower) { console.log("收到花:" + flower); } }; xiaoming.sendFlower(A); // ----------- 示例2 -------------- // 使用代理1 var Flower = function() {}; var xiaoming = { sendFlower: function(target) { var flower = new Flower(); B.receiveFlower(flower); } }; var B = { receiveFlower: function(flower) { A.receiveFlower(flower); } }; var A = { receiveFlower: function(flower) { console.log("收到花:" + flower); } }; xiaoming.sendFlower(B); //------------- 示例3 --------------- /* * 使用代理2 * 從示例1和示例2,看不出使用代理有什么用處,B只不過是從中間轉(zhuǎn)手了一次。 * 接下來,我們想一下。給喜歡的人送花,怎樣才能提高成功率呢? * 我們都知道,人有心情好和心情差的時(shí)候,當(dāng)美女心情好的時(shí)候,送花成功的概率自然要大些。 * 于是,我們將代理升級(jí),監(jiān)聽美女的心情,心情好的時(shí)候再給她送花。 * 為了演示,我們假設(shè)2秒后,A的心情變好。 */ var Flower = function() {}; var xiaoming = { sendFlower: function(target) { var flower = new Flower(); B.receiveFlower(flower); } }; var B = { receiveFlower: function(flower) { A.listenGoodMood(function() { A.receiveFlower(flower); }); } }; var A = { receiveFlower: function(flower) { console.log("收到花:" + flower); }, listenGoodMood: function(fn) { setTimeout(function() { fn.apply(this, arguments); }, 2000); } }; xiaoming.sendFlower(B); // ---------- 示例4 --------------- /* * 【代理模式用處】:虛擬代理 * 這里以加載圖片為例,我們都知道當(dāng)網(wǎng)絡(luò)不暢以及圖片過大時(shí),圖片加載都比較慢, * 為了更好的用戶體驗(yàn),我們都會(huì)在原圖片未加載完成前,加上loading圖片。 * */ //--4 _01未使用代理-- var myImage = (function() { var imgNode = document.createElement("img"); document.body.appendChild(imgNode); return { setSrc: function(src) { this.imgNode.src = src; } } })(); myImage.setSrc("xxx"); //--4_02使用代理-- var proxyMyImage = (function() { var img = new Image(); img.onload = function() { myImage.setSrc(this.src); }; return { setSrc: function(src) { myImage.setSrc("loading.jpg"); img.src = src; } } })(); proxyMyImage.setSrc("xxx"); /* * [注]:這里可以看到代理模式的好處:在不改變?cè)薪涌诘耐瑫r(shí),可以為系統(tǒng)添加新的行為。 */ //--------- 示例5--------------- /* * 【代理模式用處】:合并http請(qǐng)求 * 這里以選擇文件同步為例。 * 以往用戶同步文件,在用戶選中的時(shí)候就觸發(fā),這種方法做到了實(shí)時(shí)性,但無疑增加了網(wǎng)絡(luò)的開銷。 * 實(shí)際在使用的過程中,往往并不需要立刻就同步。 * 以下通過代理模式,將在用戶選中文件2秒后進(jìn)行同步請(qǐng)求。 * */ // --- 包含一段html代碼,請(qǐng)自行添加到一個(gè)文件中 ------ 1 2 3 4 5 6 7 8 9 // -- 上傳文件 -- var synchronizeFile = function(id) { console.log("開始同步文件:" + id); }; var proxySynchronizeFiles = (function() { var fileCache = [], timer; return function(id) { fileCache.push(id); if(timer) { return; } timer = setTimeout(function() { synchronizeFile(fileCache.join(",")); clearTimeout(timer); timer = null; checkArr.length = 0; }, 2000); } })(); var checkArr = document.getElementsByTagName("input"); for(var i = 0, c; c = checkArr[i++];) { c.onclick = function() { if(this.checked == true) { proxySynchronizeFiles(this.id); } } } // ------------ 示例6 ----------------- /* * 【代理模式用處】:緩存代理 * 以計(jì)算器為例,比如計(jì)算某些數(shù)的乘積,當(dāng)參數(shù)重復(fù)時(shí),我們希望不用重復(fù)計(jì)算,直接返回結(jié)果。 * 以下用到代理模式做緩存。 */ var mult = function() { if(!arguments) { console.log("請(qǐng)輸入?yún)?shù)"); return; } var a = 1; for(var i = 0, b; b = arguments[i++];) { a = a * b; } return a; }; var proxyMult = (function() { var cache = {}; return function() { var str = Array.prototype.join.call(arguments, ","); if(str in cache) { console.log("重復(fù)return."); return cache[str]; } return cache[str] = mult.apply(this, arguments); } })(); console.log(proxyMult(2, 3, 4)); console.log(proxyMult(2, 3, 4)); //------------ 示例7 -------------- /* * 緩存代理升級(jí) - 通用版計(jì)算 * */ var mult = function() { if(!arguments) { return; } var t = 1; for(var i = 0, a; a = arguments[i++];) { t = t * a; } return t; }; var plus = function() { if(!arguments) { return; } var t = 0; for(var a of arguments) { t += a; } return t; }; var createProxyCaculate = function(fn) { var cache = {}; return function() { var str = Array.prototype.join.call(arguments, ","); if(str in cache) { console.log("重復(fù)return" + str); return cache[str]; } return cache[str] = fn.apply(this, arguments); } }; var proxyMult = createProxyCaculate(mult); var proxyPlus = createProxyCaculate(plus); console.log(proxyMult(2, 3, 4)); console.log(proxyMult(2, 3, 4));
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)頁題目:JavaScript設(shè)計(jì)模式之代理模式詳解
標(biāo)題網(wǎng)址:http://www.ef60e0e.cn/article/gpdeih.html