欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2009年08月04日 00:18:17   作者:  
JavaScript支持函數重載嗎?可以說不支持,也可以說支持。說不支持,是因為JavaScript不能好像其它原生支持函數重載的語言一樣,直接寫多個同名函數,讓編譯器來判斷某個調用對應的是哪一個重載。
JavaScript支持重載嗎?
JavaScript支持函數重載嗎?可以說不支持,也可以說支持。說不支持,是因為JavaScript不能好像其它原生支持函數重載的語言一樣,直接寫多個同名函數,讓編譯器來判斷某個調用對應的是哪一個重載。說支持,是因為JavaScript函數對參數列表不作任何限制,可以在函數內部模擬對函數重載的支持。
實際上,在很多著名的開源庫當中,我們都可以看到函數內部模擬重載支持的設計。例如說jQuery的jQuery.extend方法,就是通過參數類型判斷出可選參數是否存在,如果不存在的話就對參數進行移位以確保后面的邏輯正確運行。我相信很多人在寫JavaScript時也寫過類似的代碼,以求為功能豐富的函數提供一個(或多個)簡單的調用入口。
不過做種做法一個根本的問題,那就是違反了DRY原則。每個支持重載的函數內部都多出來一段代碼,用于根據參數個數和參數類型處理重載,這些代碼暗含著重復的邏輯,寫出來卻又每一段都不一樣。此外,這些代碼要維護起來也不容易,因為閱讀代碼時你并不能一眼看出函數支持的幾種重載方式是什么,要對重載做出維護自然也困難。
描述重載入口的DSL
我希望能夠在JavaScript中以一種簡單的方式來描述重載入口。最好就如同在其它語言中一樣,使用函數簽名來區(qū)分重載入口,因為我認為函數簽名就是這方面最好的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做成一個靜態(tài)類,靜態(tài)方法返回的是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關鍵字要多得多。在我們之前制定的規(guī)則當中,這也無法描述的,因此我們要引入一個不和類名沖突的符號來表示C#中的params。我選擇了用"..."表示params,意思是這里出現任意多個參數都是可以接受的。讓我們看看jQuery.extend的重載應該如何描述:
復制代碼 代碼如下:

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

小結
在這篇文章當中,我們嘗試設計出一種適用于JavaScript且易讀易維護的函數重載寫法。在下一篇文章當中,我們將會嘗試編寫Overload類,以實現這一設計。

相關文章

  • 詳解Javascript幾種跨域方式總結

    詳解Javascript幾種跨域方式總結

    在實際開發(fā)中我們經常需要獲取其他域的資源,本篇文章主要介紹了詳解Javascript幾種跨域方式總結,有興趣的可以了解一下。
    2017-02-02
  • js圖片閃動特效可以控制間隔時間如幾分鐘閃動一下

    js圖片閃動特效可以控制間隔時間如幾分鐘閃動一下

    這篇文章主要介紹一個圖片閃動特效,可以控制間隔時間如幾分鐘閃動一下,需要的朋友不要錯過
    2014-08-08
  • 小程序云開發(fā)部署攻略(圖文教程)

    小程序云開發(fā)部署攻略(圖文教程)

    微信小程序的云開發(fā)功能剛剛上線,這篇文章主要介紹了小程序云開發(fā)部署攻略(圖文教程),小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • 使用原生JS實現火鍋點餐小程序(面向對象思想)

    使用原生JS實現火鍋點餐小程序(面向對象思想)

    這篇文章主要介紹了使用原生JS實現火鍋點餐小程序(面向對象思想),在這里小程序使用的是es6開發(fā)標準,本文通過代碼展示,截圖的形式給大家介紹,需要的朋友可以參考下
    2019-12-12
  • 微信小程序npm引入vant-weapp的踩坑記錄

    微信小程序npm引入vant-weapp的踩坑記錄

    這篇文章主要給大家介紹了關于微信小程序npm引入vant-weapp的踩坑記錄,文中通過示例代碼介紹的非常詳細,對大家學習或者使用微信小程序具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-08-08
  • JavaScript最完整的深淺拷貝實現方式詳解

    JavaScript最完整的深淺拷貝實現方式詳解

    這篇文章主要為大家詳細介紹了JavaScript最完整的深淺拷貝實現方式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • javascript簡單實現圖片預加載

    javascript簡單實現圖片預加載

    本文是給大家分享一段簡單的實現圖片預加載技術的javascript代碼,超級精簡,卻很實用,這里推薦給大家
    2014-12-12
  • JavaScript閉包實例講解

    JavaScript閉包實例講解

    眾所周知,JavaScript沒有塊級作用域,只有函數作用域。那就意味著定義在函數中的參數和變量在函數外部是不可見的,而在一個函數內部任何位置定義的變量,在該函數內部任何地方都可見
    2014-04-04
  • JavaScript執(zhí)行效率與性能提升方案

    JavaScript執(zhí)行效率與性能提升方案

    如何提升JavaScript執(zhí)行效率與性能在前端開發(fā)中位于一個很重要的地方,這節(jié)來研究下如何在平時做項目過程中,提升JavaScript性能與運行效率,需要的朋友可以參考下
    2012-12-12
  • 設為首頁加入收藏兼容360/火狐/谷歌/IE等主流瀏覽器的代碼

    設為首頁加入收藏兼容360/火狐/谷歌/IE等主流瀏覽器的代碼

    不用找了我試過好多次ie、火狐、谷歌瀏覽器此代碼都是不可逆兼容,想把這個問題完全解決,方法就是像其他主流網站一樣,下面是我的簡單解決方案
    2013-03-03

最新評論