天天看點

《JavaScript應用程式設計》一一2.12 範型程式設計與集合多态

本節書摘來華章計算機出版社《javascript應用程式設計》一書中的第2章,第2.12節,作者:eric elliott 更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

範型程式設計是指在多種資料類型上提供可複用的一套算法與資料結構,這種語言機制的産生緣由在于算法通常能适配多種資料類型。範型程式設計一般從幾種特定的資料類型實作開始入手,随後逐漸将之抽象成為能夠相容更多資料類型的通用版本。

範型程式設計并沒有對不同類型的資料做算法差異性處理,相反,被傳入的每種資料類型必須實作算法中所約定的功能,這些功能被稱為“接口需求”。

範型程式設計具有參數多态性,它是作用于範類型參數上的邏輯分支,相比之下,重載則需要對所有不同類型的參數分别建立一套處理邏輯。

範型程式設計的理念與函數式程式設計緊密相關,因為函數式程式設計的最佳使用場景常見于單一函數對應多種資料類型。

在多數語言中,範型程式設計關注的是如何讓算法去相容不同類型的集合,在javascript中,集合可以包含任意類型的資料結構,許多程式員為了讓算法适配集合中的元素,采用了鴨子類型的代碼設計方式,他們忘記了多數javascript的内建對象方法本身就是支援範型調用的,這些方法可以在多種資料類型上使用。

javascript中的集合有對象與數組兩種類型,它倆的關鍵不同之處在于,對象采用的是鍵值對的組織方式,而數組中的内容則是按照次序依次排開,對象不能保證内容的順序而數組可以,除此之外,它們的行為都極為相似。實作一個相容所有傳入集合類型的函數帶來的複用價值是顯而易見的。

大部分作用于數組上的函數同樣也應當可以在對象上調用,舉例來說,假設你想從一個數組或對象集合中擷取随機值。

最為簡單的方法是通過數字索引下标找到相應的随機元素,但當集合類型為對象時,需要使用重載的方式将對象轉換為數組。

randomitem()函數的實作很簡單,首先确認傳入集合的類型是否為數組,如果不是則将之轉換為數組,最後使用内置方法math.random()擷取數組中的随機元素并傳回:

測試用例驗證被傳回的元素是否存在于目标集合中。

不同于真正意義上的範型,上述代碼将對象視為一種特殊的資料類型,并在内部采用了不同的邏輯實作。由于在javascript中數組是對象的子集,是以從理論上看,任何作用在對象之上的操作同樣适用于數組,換句話說,在javascript中,對象中的大部分範型方法無需做額外的邏輯處理,就可以在數組上執行。

集合的多态性對于提升代碼複用性與api一緻性來說是一項非常有效的政策,在諸如jquery、underscore這樣的類庫中,大部分方法同時可以相容對象與數組。

javascript 1.6版本中為數組與字元串引入了不少内置的範型方法,在支援1.6版本文法的javascript引擎中,你可以在字元串對象上使用諸如every()這樣的數組方法。

繼續閱讀