<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      讓 JavaScript 輕松支持函數重載 (Part 1 - 設計)

      2009-07-02 09:18  Cat Chen  閱讀(7578)  評論(12)    收藏  舉報

      JavaScript支持重載嗎?

      JavaScript支持函數重載嗎?可以說不支持,也可以說支持。說不支持,是因為JavaScript不能好像其它原生支持函數重載的語言一樣,直接寫多個同名函數,讓編譯器來判斷某個調用對應的是哪一個重載。說支持,是因為JavaScript函數對參數列表不作任何限制,可以在函數內部模擬對函數重載的支持。

      實際上,在很多著名的開源庫當中,我們都可以看到函數內部模擬重載支持的設計。例如說jQuery的jQuery.extend方法,就是通過參數類型判斷出可選參數是否存在,如果不存在的話就對參數進行移位以確保后面的邏輯正確運行。我相信很多人在寫JavaScript時也寫過類似的代碼,以求為功能豐富的函數提供一個(或多個)簡單的調用入口。

      不過做種做法一個根本的問題,那就是違反了DRY原則。每個支持重載的函數內部都多出來一段代碼,用于根據參數個數和參數類型處理重載,這些代碼暗含著重復的邏輯,寫出來卻又每一段都不一樣。此外,這些代碼要維護起來也不容易,因為閱讀代碼時你并不能一眼看出函數支持的幾種重載方式是什么,要對重載做出維護自然也困難。

      描述重載入口的DSL

      我希望能夠在JavaScript中以一種簡單的方式來描述重載入口。最好就如同在其它語言中一樣,使用函數簽名來區分重載入口,因為我認為函數簽名就是這方面最好的DSL。我假想中最符合JavaScript語法的重載入口描述DSL應該是這樣子的:

      var sum = new Overload();
      sum.add("Number, Number",
        function(x, y) { return x + y; });
      sum.add("Number, Number, Number",
        function(x, y, z) { return x + y + z; });

      在描述好重載入口與對應函數體后,對sum函數的調用應該是這樣子的:

      sum(1, 2);
      sum(1, 2, 3);

      上述代碼在我看來非常清晰,也非常容易維護——你可以一眼看得出重載入口的簽名,并且要修改或者增加重載入口都是很容易的事情。但是我們遇到了一個問題,那就是JavaScript里面的函數是不能new出來的,通過new Overload()獲得的對象一定不能被調用,為此我們只能把Overload做成一個靜態類,靜態方法返回的是Function實例:

      var sum = Overload
        .add("Number, Number",
          function(x, y) { return x + y; })
        .add("Number, Number, Number",
          function(x, y, z) { return x + y + z; });

      必要的重載入口支持

      想象一下,有哪些常見的JavaScript函數入口是用上述DSL無法描述的?我所知道的有兩種:

      任意類型參數

      假想我們要寫一個each函數,對于Array就迭代它的下標,對于其它類型就迭代它的所有成員,這兩個函數入口的參數列表如何聲明?如果用C#,我們會如此描述兩個函數入口:

      void Each(IEnumerable iterator) { }
      void Each(object iterator) { }

      然而在JavaScript當中,Object不是一切類型的基類,(100) instanceof Object的結果為false,所以我們不能用Object來指代任意類型,必須引入一個新的符號來指代任意類型。考慮到這個符號不應該與任何可能存在的類名沖突,所以我選擇了用"*"來表示任意類型。上述C#代碼對應的JavaScript應該是這樣子的:

      var each = Overload
        .add("Array",
          function(array) { })
        .add("*",
          function(object) { });

      任意數量參數

      在JavaScript的函數里面,要求支持任意數量參數是很常見的需求,相信使用率比C#里面的params關鍵字要多得多。在我們之前制定的規則當中,這也無法描述的,因此我們要引入一個不和類名沖突的符號來表示C#中的params。我選擇了用"..."表示params,意思是這里出現任意多個參數都是可以接受的。讓我們看看jQuery.extend的重載應該如何描述:

      var extend = Overload
        .add("*, ...",
          function(target) { })
        .add("Boolean, *, ...",
          function(deep, target) { });

      小結

      在這篇文章當中,我們嘗試設計出一種適用于JavaScript且易讀易維護的函數重載寫法。在下一篇文章當中,我們將會嘗試編寫Overload類,以實現這一設計。如果你不希望錯過的話,歡迎訂閱:

      主站蜘蛛池模板: 亚洲AV成人片不卡无码| 国产精品久久自在自线不卡| 99久久99久久精品国产片| 国产精品国产三级国产试看| 色爱无码av综合区| 五月婷之久久综合丝袜美腿| 国产精品成人中文字幕| 日韩精品福利一二三专区| 99中文字幕国产精品| 少妇粗大进出白浆嘿嘿视频| 另类 专区 欧美 制服| 少妇粗大进出白浆嘿嘿视频| 欧美人与动牲猛交A欧美精品| 性少妇tubevⅰdeos高清| 日韩三级一区二区在线看| 97se亚洲综合自在线| 欧美在线观看www| 日韩人妻无码精品久久久不卡| 农村妇女野外一区二区视频| 国产99视频精品免费视频36| 亚洲人成网站18禁止无码| 亚洲人妻精品一区二区| 永久免费无码成人网站| 久久亚洲精品国产精品| 久久精品国产一区二区蜜芽| 蜜桃av无码免费看永久| 野花社区www高清视频| 日韩人妻精品中文字幕专区| 久久月本道色综合久久| 九九在线精品国产| 极品美女自拍偷精品视频| 精品无人区卡一卡二卡三乱码 | 日韩精品人妻中文字幕| 成年午夜免费韩国做受视频| 国产高在线精品亚洲三区| 在线精品另类自拍视频| 欧美日韩不卡合集视频| 国产精品一品二区三区日韩| a级黑人大硬长爽猛出猛进| 亚洲鸥美日韩精品久久| h无码精品动漫在线观看|