<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、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                代理是一個對象,它可以用來控制對本體對象的訪問,它與本體對象實現了同樣的接口,代理對象會把所有的調用方法傳遞給本體對象的;代理模式最基本的形式是對訪問進行控制,而本體對象則負責執行所分派的那個對象的函數或者類,簡單的來講本地對象注重的去執行頁面上的代碼,代理則控制本地對象何時被實例化,何時被使用;我們在上面的單體模式中使用過一些代理模式,就是使用代理模式實現單體模式的實例化,其他的事情就交給本體對象去處理; 代理的優點: 代理對象可以代替本體被實例化,并使其可以被遠程訪問; 它還可以把本體實例化推遲到真正需要的時候;對于實例化比較費時的本體對象,或者因為尺寸比較大以至于不用時不適于保存在內存中的本體,我們可以推遲實例化該對象; 我們先來理解代理對象代替本體對象被實例化的列子;比如現在京東ceo想送給奶茶妹一個禮物,但是呢假如該ceo不好意思送,或者由于工作忙沒有時間送,那么這個時候他就想委托他的經紀人去做這件事,于是我們可以使用代理模式來編寫如下代碼: ~~~ // 先申明一個奶茶妹對象 var TeaAndMilkGirl = function(name) { this.name = name; }; // 這是京東ceo先生 var Ceo = function(girl) { this.girl = girl; // 送結婚禮物 給奶茶妹 this.sendMarriageRing = function(ring) { console.log("Hi " + this.girl.name + ", ceo送你一個禮物:" + ring); } }; // 京東ceo的經紀人是代理,來代替送 var ProxyObj = function(girl){ this.girl = girl; // 經紀人代理送禮物給奶茶妹 this.sendGift = function(gift) { // 代理模式負責本體對象實例化 (new Ceo(this.girl)).sendMarriageRing(gift); } }; // 初始化 var proxy = new ProxyObj(new TeaAndMilkGirl("奶茶妹")); proxy.sendGift("結婚戒"); // Hi 奶茶妹, ceo送你一個禮物:結婚戒 ~~~ 代碼如上的基本結構,TeaAndMilkGirl 是一個被送的對象(這里是奶茶妹);Ceo 是送禮物的對象,他保存了奶茶妹這個屬性,及有一個自己的特權方法sendMarriageRing 就是送禮物給奶茶妹這么一個方法;然后呢他是想通過他的經紀人去把這件事完成,于是需要創建一個經濟人的代理模式,名字叫ProxyObj ;他的主要做的事情是,把ceo交給他的禮物送給ceo的情人,因此該對象同樣需要保存ceo情人的對象作為自己的屬性,同時也需要一個特權方法sendGift ,該方法是送禮物,因此在該方法內可以實例化本體對象,這里的本體對象是ceo送花這件事情,因此需要實例化該本體對象后及調用本體對象的方法(sendMarriageRing). 最后我們初始化是需要代理對象ProxyObj;調用ProxyObj 對象的送花這個方法(sendGift)即可; 對于我們提到的優點,第二點的話,我們下面可以來理解下虛擬代理,虛擬代理用于控制對那種創建開銷很大的本體訪問,它會把本體的實例化推遲到有方法被調用的時候;比如說現在有一個對象的實例化很慢的話,不能在網頁加載的時候立即完成,我們可以為其創建一個虛擬代理,讓他把該對象的實例推遲到需要的時候。 理解使用虛擬代理實現圖片的預加載 在網頁開發中,圖片的預加載是一種比較常用的技術,如果直接給img標簽節點設置src屬性的話,如果圖片比較大的話,或者網速相對比較慢的話,那么在圖片未加載完之前,圖片會有一段時間是空白的場景,這樣對于用戶體驗來講并不好,那么這個時候我們可以在圖片未加載完之前我們可以使用一個loading加載圖片來作為一個占位符,來提示用戶該圖片正在加載,等圖片加載完后我們可以對該圖片直接進行賦值即可;下面我們先不用代理模式來實現圖片的預加載的情況下代碼如下: 第一種方案:不使用代理的預加載圖片函數如下 ~~~ // 不使用代理的預加載圖片函數如下 var myImage = (function(){ var imgNode = document.createElement("img"); document.body.appendChild(imgNode); var img = new Image(); img.onload = function(){ imgNode.src = this.src; }; return { setSrc: function(src) { imgNode.src = "http://img.lanrentuku.com/img/allimg/1212/5-121204193Q9-50.gif"; img.src = src; } } })(); // 調用方式 myImage.setSrc("https://img.alicdn.com/tps/i4/TB1b_neLXXXXXcoXFXXc8PZ9XXX-130-200.png"); ~~~ 如上代碼是不使用代理模式來實現的代碼; 第二種方案:使用代理模式來編寫預加載圖片的代碼如下: ~~~ 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) { myImage.setSrc("http://img.lanrentuku.com/img/allimg/1212/5-121204193Q9-50.gif"); img.src = src; } } })(); // 調用方式 ProxyImage.setSrc("https://img.alicdn.com/tps/i4/TB1b_neLXXXXXcoXFXXc8PZ9XXX-130-200.png"); ~~~ 第一種方案是使用一般的編碼方式實現圖片的預加載技術,首先創建imgNode元素,然后調用myImage.setSrc該方法的時候,先給圖片一個預加載圖片,當圖片加載完的時候,再給img元素賦值,第二種方案是使用代理模式來實現的,myImage 函數只負責創建img元素,代理函數ProxyImage 負責給圖片設置loading圖片,當圖片真正加載完后的話,調用myImage中的myImage.setSrc方法設置圖片的路徑;他們之間的優缺點如下: 第一種方案一般的方法代碼的耦合性太高,一個函數內負責做了幾件事情,比如創建img元素,和實現給未加載圖片完成之前設置loading加載狀態等多項事情,未滿足面向對象設計原則中單一職責原則;并且當某個時候不需要代理的時候,需要從myImage 函數內把代碼刪掉,這樣代碼耦合性太高。 第二種方案使用代理模式,其中myImage 函數只負責做一件事,創建img元素加入到頁面中,其中的加載loading圖片交給代理函數ProxyImage 去做,當圖片加載成功后,代理函數ProxyImage 會通知及執行myImage 函數的方法,同時當以后不需要代理對象的話,我們直接可以調用本體對象的方法即可; 從上面代理模式我們可以看到,代理模式和本體對象中有相同的方法setSrc,這樣設置的話有如下2個優點: 用戶可以放心地請求代理,他們只關心是否能得到想要的結果。假如我門不需要代理對象的話,直接可以換成本體對象調用該方法即可。 在任何使用本體對象的地方都可以替換成使用代理。 當然如果代理對象和本體對象都返回一個匿名函數的話,那么也可以認為他們也具有一直的接口;比如如下代碼: ~~~ var myImage = (function(){ var imgNode = document.createElement("img"); document.body.appendChild(imgNode); return function(src){ imgNode.src = src; } })(); // 代理模式 var ProxyImage = (function(){ var img = new Image(); img.onload = function(){ myImage(this.src); }; return function(src) { myImage("http://img.lanrentuku.com/img/allimg/1212/5-121204193Q9-50.gif"); img.src = src; } })(); // 調用方式 ProxyImage("https://img.alicdn.com/tps/i4/TB1b_neLXXXXXcoXFXXc8PZ9XXX-130-200.png"); ~~~ 虛擬代理合并http請求的理解: 比如在做后端系統中,有表格數據,每一條數據前面有復選框按鈕,當點擊復選框按鈕時候,需要獲取該id后需要傳遞給給服務器發送ajax請求,服務器端需要記錄這條數據,去請求,如果我們每當點擊一下向服務器發送一個http請求的話,對于服務器來說壓力比較大,網絡請求比較頻繁,但是如果現在該系統的實時數據不是很高的話,我們可以通過一個代理函數收集一段時間內(比如說2-3秒)的所有id,一次性發ajax請求給服務器,相對來說網絡請求降低了, 服務器壓力減少了; ~~~ // 首先html結構如下: <p> <label>選擇框</label> <input type="checkbox" class="j-input" data-id="1"/> </p> <p> <label>選擇框</label> <input type="checkbox" class="j-input" data-id = "2"/> </p> <p> <label>選擇框</label> <input type="checkbox" class="j-input" data-id="3"/> </p> <p> <label>選擇框</label> <input type="checkbox" class="j-input" data-id = "4"/> </p> ~~~ 一般的情況下 JS如下編寫 ~~~ <script> var checkboxs = document.getElementsByClassName("j-input"); for(var i = 0,ilen = checkboxs.length; i < ilen; i+=1) { (function(i){ checkboxs[i].onclick = function(){ if(this.checked) { var id = this.getAttribute("data-id"); // 如下是ajax請求 } } })(i); } </script> ~~~ 下面我們通過虛擬代理的方式,延遲2秒,在2秒后獲取所有被選中的復選框的按鈕id,一次性給服務器發請求。 通過點擊頁面的復選框,選中的時候增加一個屬性isflag,沒有選中的時候刪除該屬性isflag,然后延遲個2秒,在2秒后重新判斷頁面上所有復選框中有isflag的屬性上的id,存入數組,然后代理函數調用本體函數的方法,把延遲2秒后的所有id一次性發給本體方法,本體方法可以獲取所有的id,可以向服務器端發送ajax請求,這樣的話,服務器的請求壓力相對來說減少了。 代碼如下: ~~~ // 本體函數 var mainFunc = function(ids) { console.log(ids); // 即可打印被選中的所有的id // 再把所有的id一次性發ajax請求給服務器端 }; // 代理函數 通過代理函數獲取所有的id 傳給本體函數去執行 var proxyFunc = (function(){ var cache = [], // 保存一段時間內的id timer = null; // 定時器 return function(checkboxs) { // 判斷如果定時器有的話,不進行覆蓋操作 if(timer) { return; } timer = setTimeout(function(){ // 在2秒內獲取所有被選中的id,通過屬性isflag判斷是否被選中 for(var i = 0,ilen = checkboxs.length; i < ilen; i++) { if(checkboxs[i].hasAttribute("isflag")) { var id = checkboxs[i].getAttribute("data-id"); cache[cache.length] = id; } } mainFunc(cache.join(',')); // 2秒后需要給本體函數傳遞所有的id // 清空定時器 clearTimeout(timer); timer = null; cache = []; },2000); } })(); var checkboxs = document.getElementsByClassName("j-input"); for(var i = 0,ilen = checkboxs.length; i < ilen; i+=1) { (function(i){ checkboxs[i].onclick = function(){ if(this.checked) { // 給當前增加一個屬性 this.setAttribute("isflag",1); }else { this.removeAttribute('isflag'); } // 調用代理函數 proxyFunc(checkboxs); } })(i); } ~~~ 理解緩存代理: 緩存代理的含義就是對第一次運行時候進行緩存,當再一次運行相同的時候,直接從緩存里面取,這樣做的好處是避免重復一次運算功能,如果運算非常復雜的話,對性能很耗費,那么使用緩存對象可以提高性能;我們可以先來理解一個簡單的緩存列子,就是網上常見的加法和乘法的運算。代碼如下: ~~~ // 計算乘法 var mult = function(){ var a = 1; for(var i = 0,ilen = arguments.length; i < ilen; i+=1) { a = a*arguments[i]; } return a; }; // 計算加法 var plus = function(){ var a = 0; for(var i = 0,ilen = arguments.length; i < ilen; i+=1) { a += arguments[i]; } return a; } // 代理函數 var proxyFunc = 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 = proxyFunc(mult); console.log(proxyMult(1,2,3,4)); // 24 console.log(proxyMult(1,2,3,4)); // 緩存取 24 var proxyPlus = proxyFunc(plus); console.log(proxyPlus(1,2,3,4)); // 10 console.log(proxyPlus(1,2,3,4)); // 緩存取 10 ~~~
                  <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>

                              哎呀哎呀视频在线观看