天天看點

讀Zepto源碼之代碼結構

雖然最近工作中沒有怎麼用 zepto ,但是據說 zepto 的源碼比較簡單,而且網上的資料也比較多,是以我就挑了 zepto 下手,希望能為以後閱讀其他架構的源碼打下基礎吧。

本文閱讀的源碼為 zepto1.2.0

閱讀zepto之前需要了解 javascript 原型鍊和閉包的知識,推薦閱讀王福朋的這篇文章:深入了解 Javascript 原型和閉包,寫得很詳細,也非常易于閱讀。

如果在編輯器中将 zepto 的源碼折疊起來,看到的就跟上面的代碼一樣。

zepto 的核心是一個閉包,加載完畢後立即執行。然後暴露給全局變量 <code>zepto</code> ,如果 <code>$</code> 沒有定義,也将 <code>$</code> 指派為 <code>zepto</code> 。

在這部分中,我們先不關注 zepto 的具體實作,隻看核心的結構,是以我将zepto中的邏輯先移除,得出如下的核心結構:

在源碼中,可以看出, <code>$</code> 其實是一個函數,同時在 <code>$</code> 身上又挂了很多屬性和方法(這裡展現在 <code>$.fn</code> 身上,其他的會在後續的文章中談到)。

我們在使用 zepto 的時候,會用 <code>$</code> 去擷取 <code>dom</code> ,并且在這些 <code>dom</code> 對象身上都有 zepto 定義的各種各樣的操作方法。

從上面的僞代碼中,可以看到,<code>$</code> 其實調用了 <code>zepto.init()</code> 方法,在 <code>init</code> 方法中,會擷取到 <code>dom</code> 元素集合,然後将集合交由 <code>zepto.Z()</code> 方法處理,而 <code>zepto.Z</code> 方法傳回的是函數 <code>Z</code> 的一個執行個體。

函數 <code>Z</code> 會将 <code>doms</code> 展開,變成執行個體的屬性,<code>key</code> 為對應 <code>domObj</code> 的索引, 并且設定執行個體的 <code>length</code> 屬性。

讀到這裡,你可能會有點疑惑,<code>$</code> 最終傳回的是 <code>Z</code> 函數的執行個體,但是 <code>Z</code> 函數明明沒有 <code>dom</code> 的操作方法啊,這些操作方法都定義在 <code>$.fn</code> 身上,為什麼 <code>$</code> 可以調用這些方法呢?

其實關鍵在于這句代碼 <code>Z.prototype = $.fn</code> ,這句代碼将 <code>Z</code> 的 <code>prototype</code> 指向 <code>$.fn</code> ,這樣,<code>Z</code> 的執行個體就繼承了 <code>$.fn</code> 的方法。

既然這樣就已經讓 <code>Z</code> 的執行個體繼承了 <code>$.fn</code> 的方法,那 <code>zepto.Z.prototype = $.fn</code> 又是為什麼呢?

如果我們再看源碼,會發現有這樣的一個方法:

這個方法是用來判讀一個對象是否為 zepto 對象,這是通過判斷這個對象是否為 <code>zepto.Z</code> 的執行個體來完成的,是以需要将 <code>zepto.Z</code> 和 <code>Z</code> 的 <code>prototype</code> 指向同一個對象。 <code>isZ</code> 方法會在 <code>init</code> 中用到,後面也會介紹。

本文轉自帥氣的頭頭部落格51CTO不可靠,原文連結http://blog.51cto.com/12902932/1950349如需轉載請自行聯系原作者

sshpp

繼續閱讀