代理模式是為一個對象提供一個代用品或占位符,以便控制對它的訪問
代理模式的用處(個人理解):為了保障當(dāng)前對象的單一職責(zé)(相對獨(dú)立性),而需要創(chuàng)建另一個對象來處理調(diào)用當(dāng)前對象之前的一些邏輯以提高代碼的效率、狀態(tài)判斷等。
代理模式中最常用的是虛擬代理和緩存代理
一、虛擬代理
虛擬代理是把一些開銷很大的對象,延遲到真正需要它的時候才去創(chuàng)建執(zhí)行
示例: 虛擬代理實現(xiàn)圖片預(yù)加載
// 圖片加載函數(shù)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 ); }; return { setSrc: function(src){ // 圖片未被載入時,加載一張?zhí)崾緢D片 myImage.setSrc("file://c:/loading.png"); img.src = src; } }})();// 調(diào)用代理對象加載圖片proxyImage.setSrc( "http://images/qq.jpg");示例: 虛擬代理合并HTTP請求
假設(shè)一個功能需要頻繁的進(jìn)行網(wǎng)絡(luò)請求,這會造成相當(dāng)大的開銷,解決方案是通過一個代理函數(shù)來收集一段時間之內(nèi)的請求,一次性發(fā)給服務(wù)器。
例如:做一個文件同步的功能,當(dāng)我們選中一個文件時,就同步到另外一臺備用服務(wù)器上
// 文件同步函數(shù)var synchronousFile = function( id ){ console.log( "開始同步文件,id為:" + id );}// 使用代理合并請求var proxySynchronousFile = (function(){ var cache = [], // 保存一段時間內(nèi)需要同步的ID timer; // 定時器指針 return function( id ){ cache[cache.length] = id; if( timer ){ return; } timer = setTimeout( function(){ proxySynchronousFile( cache.join( "," ) ); // 2s 后向本體發(fā)送需要同步的ID集合 clearTimeout( timer ); // 清空定時器 timer = null; cache = []; // 晴空定時器 },2000 ); }})();// 綁定點擊事件var checkbox = document.getElementsByTagName( "input" );for(var i= 0, c; c = checkbox[i++]; ){ c.onclick = function(){ if( this.checked === true ){ // 使用代理進(jìn)行文件同步 proxySynchronousFile( this.id ); } }}二、 緩存代理
緩存代理可以為一些開銷大的運(yùn)算結(jié)果提供暫時的存儲,在下次運(yùn)算時,如果傳遞進(jìn)來的參數(shù)跟之前一致,則可以返回前面的運(yùn)算結(jié)果。
示例: 為乘法、加法等創(chuàng)建緩存代理
// 計算乘積var mult = function(){ var a = 1; for( var i = 0, l = arguments.length; i < l; i++){ a = a * arguments[i]; } return a;};// 計算加和var plus = function () { var a = 0; for( var i = 0, l = arguments.length; i < l; i++ ){ a += arguments[i]; } return a;};// 創(chuàng)建緩存代理的工廠var createProxyFactory = function( fn ){ var cache = {}; // 緩存 - 存放參數(shù)和計算后的值 return function(){ var args = Array.prototype.join.call(arguments, "-"); if( args in cache ){ // 判斷出入的參數(shù)是否被計算過 console.log( "使用緩存代理" ); return cache[args]; } return cache[args] = fn.apply( this, arguments ); }};// 創(chuàng)建代理var proxyMult = createProxyFactory( mult ), proxyPlus = createProxyFactory( plus );console.log( proxyMult( 1, 2, 3, 4 ) ); // 輸出: 24console.log( proxyMult( 1, 2, 3, 4 ) ); // 輸出: 緩存代理 24console.log( proxyPlus( 1, 2, 3, 4 ) ); // 輸出: 10console.log( proxyPlus( 1, 2, 3, 4 ) ); // 輸出: 緩存代理 10以上三個示例為大家詳細(xì)介紹了javascript代理模式,希望對大家的學(xué)習(xí)有所幫助。
新聞熱點
疑難解答