<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [Toc] >[success] # 保護代理 ~~~ 1.保護代理:'你需要滿足代理的規定的某些條件才能訪問本體',簡單的說本體喜歡玫瑰 你給你的好用康乃馨,他是不會將康乃馨給女神,直到你給了玫瑰給你朋友他才會幫你 轉交給女神 ~~~ >[success] # 虛擬代理 ~~~ 1.虛擬代理:'把一些開銷很大的對象,延遲到真正需要他的時候才創建' ~~~ >[danger] ##### 沒有使用虛擬代理來實現一個頁面生成圖片 ~~~ 1.根據書中的描述下面寫法首先是沒錯了,但是出于幾點考慮,第一個點如果網頁加載速度 過慢,那么在生成圖片的時候會出現一段空白期 ~~~ ~~~ var myImage = (function () { // 創建img 節點 var imgNode = document.createElement('img') document.body.appendChild(imgNode) return { setSrc:function (src) { imgNode.src = src } } })() myImage.setSrc('圖片地址') ~~~ >[danger] ##### 虛擬代理實現圖片預加載 ~~~ 1.通過虛擬代理的概念來解決這個問題,虛擬代理說'把一些開銷很大的對象,延遲到真正需要他的時候才創建' 針對這個概念帶入'開銷很大的是圖片加載',因此需要一個代理對象來決定在什么時候來加載這個圖片加載 2.分析代碼: 1.我們只是決定什么時候啟用myImage 2.我們不要去干涉myImage 做的事情,這個事情就是創建圖片節點 3.要做的: 1.要做的決定什么時候加載啟動myImage 方法 2.我們要保證和本體有一樣的入口方法。 ~~~ [imgonload 説明]( https://blog.csdn.net/github_37421511/article/details/84069867 ) ~~~ var myImage = (function () { // 創建img 節點 var imgNode = document.createElement('img') document.body.appendChild(imgNode) return { setSrc:function (src) { imgNode.src = src } } })() // 我是代理決定什么時候加載本體 var proxyImage = (function () { /** * 1.我們只是決定什么時候啟用myImage * 2.我們不要去干涉myImage 做的事情,這個事情就是創建圖片節點 * 要做的: * 1.要做的決定什么時候加載啟動myImage 方法 * 2.我們要保證和本體有一樣的入口這樣有一天不需要我們代理了調用本體還是好用的 * **/ var img = new Image; // 圖片加載完成時,觸發onload事件 img.onload = function () { // 調用本體 myImage.setSrc(this.src) } return { setSrc:function (src) { // 先用本地圖片作為加載,本地圖片生成速度肯定快于網站頁面請求 myImage.setSrc('本地圖片') img.src = src } } })() ~~~ >[danger] ##### 代理是多次一舉?還是有必要? ~~~ 1.上面代碼我們不用代理也能寫,寫法就像下面的效果 2.下面的代碼也完成我們想要的圖片如果沒有加載完之前,出現一個站位圖片, 為什么還需要代理一次產生額外的代碼呢? 2.1 書中舉出了一個例子,如果N年后網速變動特別快我們時候還需要這個圖片站位的方式 不需要的話我們想刪除這個站位功能可能需要對這個'MyImage',進行重寫,這類的更改就違反了 '開放封閉原則' 2.2 之前有提到一個原則'開放封閉原則',現在有一個新的原則需要引入'單一職責',引用書中的描述: 就一個類(通常也包括對象和函數等)而言,應該僅有一個引起它變化的原因。如果一個對象承擔了多項職責, 就意味著這個對象將變得巨大,引起它變化的原因會有多個。面向對象設計鼓勵將行為分布到細粒度的對象之中, 如果一個對象承擔的職責過多,等于把這些職責耦合到了一起,這種耦合會導致脆弱和低內聚的設計,帶變化發生 時,設計可能會遭到意外的破壞。 2.3.這樣的好處就像書中說的: 縱觀整個程序,我們并沒有改變或者'增加 MyImage 的接口',但是通過'代理對象', 實際上給系統'添加了新的行為'。這是符合'開放—封閉原則'。給 img 節點設置 src 和'圖片預加載這兩個功能', 被隔離在'兩個對象里',它們可以各自變化而'不影響對方'。何況就算有一天我們不再需要預加載, 那么只需要'改成請求本體'而不是'請求代理對象'即可。 ~~~ ~~~ 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 = 'https://www.baidu.com/img/bd_logo1.png'; // 當沒有加載完成使用的圖片 img.src = src; } } })(); MyImage.setSrc('https://avatars3.githubusercontent.com/u/15172026?v=4&s=460'); ~~~ >[danger] ##### 虛擬代理的案例(二)-- 節流 ~~~ 1.書中還舉了個例子,在web開發中最能引起共鳴的開銷就是網絡請求,書中根據這個前提 舉了一個例子我們有一個文件列表,當我們選中文件列表中的'checkbox'就會上傳一個文件, 在手速足夠快,足夠頻繁那么請求將會足夠頻繁 代碼如下 ~~~ * html ~~~ <body> <input type="checkbox" id="1"></input>1 <input type="checkbox" id="2"></input>2 <input type="checkbox" id="3"></input>3 <input type="checkbox" id="4"></input>4 <input type="checkbox" id="5"></input>5 <input type="checkbox" id="6"></input>6 <input type="checkbox" id="7"></input>7 <input type="checkbox" id="8"></input>8 <input type="checkbox" id="9"></input>9 </body> ~~~ * js ~~~ var synchronousFile = function(id) { console.log('發送后臺數據' + id); }; var checkbox = document.getElementsByTagName('input'); for(var i = 0, c; c = checkbox[i++];) { c.onclick = function() { // 這個this指向當前dom節點 if(this.checked === true) { synchronousFile(this.id); } } } ~~~ * 進行改造將數據緩存起來,2秒后講這些緩存的數據統一進行請求,這樣解決頻繁操作問題 ~~~ var synchronousFile = function(id) { console.log('發送后臺數據' + id); }; var proxySynchronousFile = (function() { var cache = [], // 保存一段時間內需要同步的Id timer; // 定時器 return function(id) { cache.push(id); if(timer) { // 保證不會覆蓋已經啟動的定時器 return; } timer = setTimeout(function() { synchronousFile(cache.join(',')); // 2秒內向本體發送需要同步的Id集合 clearTimeout(timer); // 清空定時器 timer = null; cache.length = 0; // 清空Id清空 }, 2000); } })(); var checkbox = document.getElementsByTagName('input'); for(var i = 0, c; c = checkbox[i++];) { c.onclick = function() { if(this.checked === true) { proxySynchronousFile(this.id); } } } ~~~ >[success] # 緩存代理 ~~~ 1.緩存代理可以為一些開銷大的運算結果提供暫時的存儲,在下次運算時,如果傳遞進來的 參數跟之前一致,則可以直接返回前面存儲的運算結果 ~~~ >[danger] ##### 之前的緩存例子 ~~~ 1.下面的代碼用es5 實現的一個緩存乘機的代碼,更多優化或者es6的寫法看歷史章節里有講過 ~~~ ~~~ var mult = (function () { var cache = {} return function () { var args = [].slice.apply(arguments) var key = args.toString() if(cache[key]){ console.log('121') return cache[key] } var count = 1 args.forEach(function (item) { count = count*item }) return cache[key] = count } })() console.log(mult(1,2,3)) console.log(mult(1,2,3)) 打印結果: 6 121 6 ~~~ >[danger] ##### 緩存代理改進上面的案例 ~~~ 1.現在這段代碼有一個不太舒服的地方,它既做了緩存,又做了乘法計算,不太符合單一原則, 我們通過代碼進行改進 ~~~ ~~~ // 目標對象 var mult = function() { console.log('開始計算乘積'); var a = 1; for (var i = 0; i< arguments.length; i++) { a = a * arguments[i]; } return a; }; mult(2, 3); // 6 mult(2, 3, 4); // 24 // 加入代理 var proxyMult = (function() { var cache = {}; return function() { var args = Array.prototype.join.call(arguments, ','); if(args in cache) { return cache[args]; } // 在代理中執行目標對象 return cache[args] = mult.apply(this, arguments); } })(); proxyMult( 1, 2, 3, 4 ); // 24 proxyMult( 1, 2, 3, 4 ); // 24 ~~~ >[danger] ##### 緩存代理用于ajax異步請求數據 ~~~ 1.內容摘抄自設計模式和開發實踐的書: 我們在常常在項目中遇到分頁的需求,同一頁的數據理論上只需要去后臺拉取一次, 這些已經拉取到的數據在某個地方被緩存之后,下次再請求同一頁的時候,便可以直 接使用之前的數據。 顯然這里也可以引入緩存代理,實現方式跟計算乘積的例子差不多,唯一不同的是, 請求數據是個異步的操作,我們無法直接把計算結果放到代理對象的緩存中,而是要 通過回調的方式。具體代碼不再贅述,讀者可以自行實現。 ~~~ >[success] # 用高階函數動態創建代理 ~~~ 1.通過傳入高階函數這種更加靈活的方式,可以為各種計算方法創建緩存代理。 現在這些計算方法被當作參數傳入一個專門用于創建緩存代理的工廠中, 這樣一來, 我們就可以為乘法、加法、減法等創建緩存代理, ~~~ >[danger] ##### 案例 ~~~ // 計算乘積 var mult = function() { var a = 1; for (var i = 0; i< arguments.length; i++) { a = a * arguments[i]; } return a; } // 計算加和 var plus = function(){ var a = 0; for ( var i = 0, l = arguments.length; i < l; i++ ){ a = a + arguments[i]; } return a; }; // 創建緩存代理的工廠 var createProxyFactory = 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 ); } }; var proxyMult = createProxyFactory( mult ), proxyPlus = createProxyFactory( plus ); alert ( proxyMult( 1, 2, 3, 4 ) ); // 輸出:24 alert ( proxyMult( 1, 2, 3, 4 ) ); // 輸出:24 alert ( proxyPlus( 1, 2, 3, 4 ) ); // 輸出:10 alert ( proxyPlus( 1, 2, 3, 4 ) ); // 輸出:10 ~~~ >[success] # 書中的其他代理 ~~~ 1.防火墻代理:控制網絡資源的訪問,保護主題不讓“壞人”接近。 2.遠程代理:為一個對象在不同的地址空間提供局部代表,在 Java 中,遠程代理可以是另一個虛擬機中的對象。 3.保護代理:用于對象應該有不同訪問權限的情況。 4.智能引用代理:取代了簡單的指針,它在訪問對象時執行一些附加操作,比如計算一個對象被引用的次數。 5.寫時復制代理:通常用于復制一個龐大對象的情況。寫時復制代理延遲了復制的過程,當對象被真正修改時,才對它6.進行復制操作。寫時復制代理是虛擬代理的一種變體,DLL(操作系統中的動態鏈接庫)是其典型運用場景。 ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看