欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

jQuery鏈式操作

系統 2523 0

兩個問題

1.jQuery的鏈式操作是如何實現的?

2.為什么要用鏈式操作?

大家認為這兩個問題哪個好回答一點呢?

?

鏈式操作

原理相信百度一下一大把,實際上鏈式操作僅僅是通過對象上的方法最后

return this

把對象再返回回來,對象當然可以繼續調用方法啦,所以就可以鏈式操作了。那么,簡單實現一個:

      
        //
      
      
        定義一個JS類
      
      
        function
      
      
         Demo() {

}

      
      
        //
      
      
        擴展它的prototype
      
      
Demo.prototype =
      
        {
    setName:
      
      
        function
      
      
         (name) {
        
      
      
        this
      
      .name = 
      
        name;
        
      
      
        return
      
      
        this
      
      
        ;
    },
    getName:
      
      
        function
      
      
         () {
        
      
      
        return
      
      
        this
      
      
        .name;
    },
    setAge:
      
      
        function
      
      
         (age) {
        
      
      
        this
      
      .age = 
      
        age;
        
      
      
        return
      
      
        this
      
      
        ;
    }
};


      
      
        //
      
      
        //工廠函數
      
      
        function
      
      
         D() {
    
      
      
        return
      
      
        new
      
      
         Demo();
}

      
      
        //
      
      
        去實現可鏈式的調用
      
      
D().setName("CJ").setAge(18).setName();
    

?

但……為什么要用呢?

一般的解釋:

節省代碼量,代碼看起來更優雅。

例如如果沒有鏈式,那么你可能需要這樣寫代碼:

      document.getElementById("ele"
      
        ).dosomething();
document.getElementById(
      
      "ele").dootherthing();
    

這個代碼中調用了兩次document.getElementById來獲取DOM樹的元素,這樣消耗比較大,而且要寫兩行,而鏈式只要寫一行,節省了代碼……

但我們也可以用緩存元素啊。比如:

      
        var
      
       ele = document.getElementById("ele"
      
        );
ele.dosomething();
ele.dootherthing();
      
    

而且兩行并沒有比一行多多少代碼,甚至相應的封裝反而使得代碼更多了。

最糟糕的是所有對象的方法返回的都是對象本身,也就是說沒有返回值,這不一定在任何環境下都適合。

舉個例子,我們想弄一個超大整數BigInteger(意思是如果用Javascript的Number保存可能會溢出的整數),順便擴展他的運算方法,會適合用鏈式操作么?

?例如運算3 1415926535 * 4 -? 271828182,如果設計成鏈式風格的方法可能會是這樣的:

      
        var
      
       result = (
      
        new
      
       BigInteger("31415926535")).multiply(
      
        new
      
       BigInteger("4")).subtract(
      
        new
      
       BigInteger("271828182"
      
        )).val();
console.log(
      
      "result == " + result);
    

這看起來似乎也很優雅,但是如果我們想要中間的結果怎么辦呢?或許會寫成這樣:

      
        var
      
       bigInteger = 
      
        new
      
       BigInteger("31415926535"
      
        );

      
      
        var
      
       result1 = bigInteger.multiply(
      
        new
      
       BigInteger("4"
      
        )).val();

      
      
        var
      
       result2 = bigInteger.subtract(
      
        new
      
       BigInteger("271828182"
      
        )).val();
console.log(
      
      "result1 == " + result1 + ", result2 == " + result2);
    

這似乎一點也不優雅了,和不用鏈式操作沒啥不同嘛!

那么如果要求是原來的BigInteger不能改變呢?好吧,鏈式操作似乎不能滿足這個需求了。

jQuery專注于DOM對象操作,而DOM的操作會在頁面上體現,不需要在Javascript中通過返回值來表示,但計算操作卻不一樣,我們很可能需要通過Javascript返回中間過程值另作他用。

在設計的時候,我們需要考慮鏈式帶來的好處和壞處,因為別人用了鏈式,所以就用鏈式,可能并不是一個很好的方案。

那么到底為什么要用鏈式操作呢?


為了更好的異步體驗

Javascript是無阻塞語言,所以他不是沒阻塞,而是不能阻塞,所以他需要通過事件來驅動,異步來完成一些本需要阻塞進程的操作。

但是異步編程是一種令人瘋狂的東西……運行時候是分離的倒不要緊,但是編寫代碼時候也是分離的就……

常見的異步編程模型有哪些呢?

  • 回調函數?

所謂的回調函數,意指先在系統的某個地方對函數進行注冊,讓系統知道這個函數的存在,然后在以后,當某個事件發生時,再調用這個函數對事件進行響應。

      
        function
      
      
         f(num, callback){  
    
      
      
        if
      
      (num<0
      
        )  {   
        alert(
      
      "調用低層函數處理!"
      
        );  
        alert(
      
      "分數不能為負,輸入錯誤!"
      
        );   
    }
      
      
        else
      
      
        if
      
      (num==0
      
        ){  
        alert(
      
      "調用低層函數處理!"
      
        );  
        alert(
      
      "該學生可能未參加考試!"
      
        );  
    }
      
      
        else
      
      
        {  
        alert(
      
      "調用高層函數處理!"
      
        );  
        setTimeout(function(){callback();}, 1000);  
    }  
}
    
      
    

這里callback則是回調函數。可以發現只有當num為非負數時候callback才會調用。

但是問題,如果我們不看函數內部,我們并不知道callback會幾時調用,在什么情況下調用,代碼間產生了一定耦合,流程上也會產生一定的混亂。

雖然回調函數是一種簡單而易于部署的實現異步的方法,但從編程體驗來說它卻不夠好。

  • 事件監聽

也就是采用事件驅動,執行順序取決于事件順序。?

      
        function
      
      
         EventTarget(){
    
      
      
        this
      
      .handlers =
      
         {};
}

EventTarget.prototype 
      
      =
      
         {
    constructor: EventTarget,
    addHandler: 
      
      
        function
      
      
        (type, handler){
        
      
      
        this
      
      .handlers[type] =
      
         [];
    },
    fire: 
      
      
        function
      
      
        (){
        
      
      
        if
      
      (!
      
        event.target){
            event.target 
      
      = 
      
        this
      
      
        ;
        }
        
      
      
        if
      
      (
      
        this
      
      .handlers[event.type 
      
        instanceof
      
      
         Array]){
            
      
      
        var
      
       handlers = 
      
        this
      
      
        .handlers[event.type];
            
      
      
        for
      
      (
      
        var
      
       i = 0, len = handlers.length, i < len; i++
      
        ){
                handlers[i](event);
            }
        }
    },
    removeHandler: 
      
      
        function
      
      
        (type, handler){
        
      
      
        if
      
      (
      
        this
      
      .handlers[type] 
      
        instanceof
      
      
         Array){
            
      
      
        var
      
       handlers = 
      
        this
      
      
        .handlers[type];
            
      
      
        for
      
      (
      
        var
      
       i = 0, le = handlers.length; i < len; i++
      
        ){
                
      
      
        if
      
      (handlers[i] ===
      
         handler){
                    
      
      
        break
      
      
        ;
                }
            }

            handlers.splice(i, 
      
      1
      
        );
        }
    }
};    
      
    

上面是《JavaScript高級程序設計》中的自定義事件實現。于是我們就可以通過addHandler來綁定事件處理函數,用fire來觸發事件,用removeHandler來刪除事件處理函數。

雖然通過事件解耦了,但流程順序更加混亂了。

  • 鏈式異步?

個人覺得鏈式操作最值得稱贊的還是其解決了異步編程模型的執行流程不清晰的問題。jQuery中$(document).ready就非常好的闡釋了這一理念。DOMCotentLoaded是一個事件,在DOM并未加載前,jQuery的大部分操作都不會奏效,但jQuery的設計者并沒有把他當成事件一樣來處理,而是轉成一種“選其對象,對其操作”的思路。$選擇了document對象,ready是其方法進行操作。這樣子流程問題就非常清晰了,在鏈條越后位置的方法就越后執行。

      (
      
        function
      
      
        (){
       
      
      
        var
      
       isReady=
      
        false
      
      ; 
      
        //
      
      
        判斷onDOMReady方法是否已經被執行過
      
      
        var
      
       readyList= [];
      
        //
      
      
        把需要執行的方法先暫存在這個數組里
      
      
        var
      
       timer;
      
        //
      
      
        定時器句柄
      
      
       ready=
      
        function
      
      
        (fn) {
              
      
      
        if
      
      
         (isReady )
                     fn.call( document);
              
      
      
        else
      
      
        
                     readyList.push( 
      
      
        function
      
      () { 
      
        return
      
       fn.call(
      
        this
      
      
        );});
              
      
      
        return
      
      
        this
      
      
        ;
       }
       
      
      
        var
      
       onDOMReady=
      
        function
      
      
        (){
              
      
      
        for
      
      (
      
        var
      
       i=0;i<readyList.length;i++
      
        ){
                     readyList[i].apply(document);
              }
              readyList 
      
      = 
      
        null
      
      
        ;
       }
       
      
      
        var
      
       bindReady = 
      
        function
      
      
        (evt){
              
      
      
        if
      
      (isReady) 
      
        return
      
      
        ;
              isReady
      
      =
      
        true
      
      
        ;
              onDOMReady.call(window);
              
      
      
        if
      
      
        (document.removeEventListener){
                     document.removeEventListener(
      
      "DOMContentLoaded", bindReady, 
      
        false
      
      
        );
              }
      
      
        else
      
      
        if
      
      
        (document.attachEvent){
                     document.detachEvent(
      
      "onreadystatechange"
      
        , bindReady);
                     
      
      
        if
      
      (window ==
      
         window.top){
                            clearInterval(timer);
                            timer 
      
      = 
      
        null
      
      
        ;
                     }
              }
       };
       
      
      
        if
      
      
        (document.addEventListener){
              document.addEventListener(
      
      "DOMContentLoaded", bindReady, 
      
        false
      
      
        );
       }
      
      
        else
      
      
        if
      
      
        (document.attachEvent){
              document.attachEvent(
      
      "onreadystatechange", 
      
        function
      
      
        (){
                     
      
      
        if
      
      ((/loaded|complete/
      
        ).test(document.readyState))
                            bindReady();
              });
              
      
      
        if
      
      (window ==
      
         window.top){
                     timer 
      
      = setInterval(
      
        function
      
      
        (){
                            
      
      
        try
      
      
        {
                                   isReady
      
      ||document.documentElement.doScroll('left');
      
        //
      
      
        在IE下用能否執行doScroll判斷dom是否加載完畢
      
      
                            }
      
        catch
      
      
        (e){
                                   
      
      
        return
      
      
        ;
                            }
                            bindReady();
                     },
      
      5
      
        );
              }
       }
})();
      
    

上面的代碼不能用$(document).ready,而應該是window.ready。

  • Deferred & Promise

CommonJS中的異步編程模型也延續了這一想法,

每一個異步任務返回一個Promise對象,該對象有一個then方法,允許指定回調函數。 ?

所以我們可以這樣寫:

f1().then(f2).then(f3);

這種方法我們無需太過關注實現,也不太需要理解異步,只要懂得通過函數選對象,通過then進行操作,就能進行異步編程。?

?

參考資料

Javascript異步編程的4種方法

jQuery鏈式操作


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。。?/p>

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 91麻豆精品国产91久久久更新时间 | 天天射天天操天天 | 日日射影院 | 国产精品伊人 | 日韩精品一区二区三区中文字幕 | 黄色a一级视频 | 成年人在线观看 | 亚洲欧美一区二区三区国产精品 | 日本黄 色 成 年 人免费观看 | 日本午夜在线 | 欧美成人a∨高清免费观看 久久亚洲欧美日韩精品专区 | 欧美激情一区二区三区视频高清 | 欧美日韩综合精品一区二区三区 | 欧美色欧美色 | 久久精品99| 久久99热成人精品国产 | 91看片在线观看 | 欧美性猛片 | 中文字幕三区 | 日韩美女福利视频 | 三极片在线观看 | 色精品一区二区三区 | 午夜欧美精品 | 成人精品视频 | 日韩欧美一区二区三区在线 | 国产精品久久久久久日本一道 | 免费观看国产大片资源视频 | 欧美日一区二区三区 | 久久久久久久久成人 | 国产精品福利片免费看 | 韩国精品一区 | 国产成人免费高清激情视频 | 久久久99精品免费观看 | 日本aaaaa高清免费看 | 欧美日韩一区二区不卡 | 一级片免费观看 | 免费一区| 国产精品久久久久久免费 | 91污网站| 久久秋霞理论电影 | 99re视频在线观看 |