Javascript – Arraylike的7種實現

發表於2015-03-24

jQuery的崛起讓ArrayLike(類陣列)在javascript中大放異彩,它的出現為一組資料的行為(函式)擴充套件提供了基礎。

類陣列和陣列相似,具有陣列的某些行為,但是它相比陣列可以更加自由的擴充套件,它的存在讓一組資料的表現不再受限於陣列,也無需去汙染陣列本身的原型——它來自javascript物件的挖掘和擴充套件,而並非javascript本身就存在的。簡單的說,它來自陣列,比陣列更加適合擴充套件。

本文原創於linkFly原文地址

這篇文章主要分為以下知識

  • 鋒芒畢露的ArrayLike
  • ArrayLike的實現
  • 其他

鋒芒畢露的ArrayLike

如果你已經瞭解了ArrayLike,這一節可以略過。

ArrayLike(類陣列/偽陣列)即擁有陣列的一部分行為,在DOM中早已表現出來,而jQuery的崛起讓ArrayLike在javascript中大放異彩。正如它的翻譯一樣:它類似於陣列。

ArrayLike物件的精妙在於它和javascript原生的Array類似,但是它是自由構建的,它來自開發者對javascript物件的擴充套件,也就是說:對於它的原型(prototype)我們可以自由定義,而不會汙染到javascript原生的Array。

過去針對一組資料的擴充套件是下面這個樣子的:

上面程式碼你們懂的,汙染了Array,在協同式開發中這簡直就是作孽啊——ArrayLike應此誕生。

ArrayLike讓你對一組資料的擴充套件不再受限於Array本身,同時也不會影響到Array,說白了就是:一組資料,肯定是有陣列來存,但是如果要對這組資料進行擴充套件,會影響到陣列原型,ArrayLike的出現則提供了一箇中間資料橋樑,ArrayLike有陣列的特性, 但是對ArrayLike的擴充套件並不會影響到原生的陣列。舉個栗子:

爸爸媽媽對你期望很高,你要好好學習,但是舍友基佬教會了你打dota,整天拉你打dota讓你沒時間看書學習,結果呢,就是打得一手好dota學習掉下去了——但是如果,你開了分身斧,讓你的分身去打dota,你自己仍然好好學習,dota學習兩不誤,而且你的分身不僅僅可以打dota,也可以去打wow,把妹,做你做不到的事情,是不是覺得這樣不就碉堡了麼!!!

沒錯,ArrayLike就是要幹這麼碉堡的事情。

常見的ArrayLike有下面這幾個,詳見:其他。

  • Arguments
  • NodeList
  • StyleSheetList
  • HTMLCollection
  • HTMLFormControlsCollection (繼承HTMLCollection)
  • HTMLOptionsCollection(繼承HTMLCollection)
  • HTMLAllCollection
  • DOMTokenList

ArrayLike的實現

第一種 – 通過閉包實現:

通過閉包實現,內部採用一個Array作為基礎,API是針對陣列進行操作,在API的實現上較差。並且不支援直接通過索引(array[0])來訪問元素,通過閉包實現上會丟失instanceof的判定,優點是夠輕。

執行結果和demo物件結構:

第二種 – 通過繼承實現:

主要亮點(應用)在保留Array的API,在Array上二次封裝,可以通過索引來訪問。

執行結果和demo物件結構:

第三種 – 通過自我維護實現:

在增刪改上需要自我維護length,相比下來很是折騰和繁瑣,只是提供一種程式碼思路,並不提倡,可以通過索引訪問,

執行結果和demo物件結構:

第四種 – 針對第一種優化:

在add中通過Array原生的APIArray.prototype.push來實現,原理是隻要呼叫過Array原生的增刪改API操作函式(僅第一次即可),則可以通過索引來訪問元素,但是instanceof的判定仍未修復。

執行結果和demo物件結構:

第五種 – 修復instenceof判定:

這種修復有點勉強,因為在ie下並沒有__proto__,所以這裡所謂的修復只不過是針對現代瀏覽器而已,只是提供一種思路,關於instenceof請參考請參考:其他

執行結果和demo物件結構:

第六種 – jQuery的實現:

jQuery建構函式繁瑣的實現不僅僅只是為了去new化,同時也修復了針對jQuery物件的判定,巧妙的將原型重新指向,讓instenceof可以在原型鏈中查詢到jQuery建構函式,使得instenceOf判定有效,讓jQuery直逼真正的javascript物件。

執行結果和demo物件結構:

第七種 – 最簡單的實現:

並沒有採用閉包,而是通過定義原型實現,實現方法類似第四種,但是原型指向正確,instenceof判定有效。

執行結果和demo物件結構:

第八種 – jQuery拆解版:

為了更好的理解jQuery的建構函式實現,所以給出了這種,jQuery.fn.init就是本例中的ArrayLike物件,jQuery只是把init掛載到jQuery.prototype上了而已。

執行結果和demo物件結構:

其實應該叫做類陣列物件的7次實現…有點標題黨的意思…..不要打臉…

其他

相關文章