雖然最近工作中沒(méi)有怎么用 zepto 之剧,但是據(jù)說(shuō) zepto 的源碼比較簡(jiǎn)單,而且網(wǎng)上的資料也比較多,所以我就挑了 zepto 下手亡容,希望能為以后閱讀其他框架的源碼打下基礎(chǔ)吧品洛。
源碼版本
本文閱讀的源碼為 zepto1.2.0
閱讀zepto之前需要了解 javascript 原型鏈和閉包的知識(shí)树姨,推薦閱讀王福朋的這篇文章:深入理解 Javascript 原型和閉包,寫得很詳細(xì)桥状,也非常易于閱讀帽揪。
源碼結(jié)構(gòu)
整體結(jié)構(gòu)
var Zepto = (function () {
...
})()
window.Zepto = Zepto
window.$ === undefined && (window.$ = Zepto)
如果在編輯器中將 zepto 的源碼折疊起來(lái),看到的就跟上面的代碼一樣辅斟。
zepto 的核心是一個(gè)閉包转晰,加載完畢后立即執(zhí)行。然后暴露給全局變量 zepto
士飒,如果 $
沒(méi)有定義查邢,也將 $
賦值為 zepto
。
核心結(jié)構(gòu)
在這部分中酵幕,我們先不關(guān)注 zepto 的具體實(shí)現(xiàn)扰藕,只看核心的結(jié)構(gòu),因此我將zepto中的邏輯先移除芳撒,得出如下的核心結(jié)構(gòu):
var zepto = {}, $
function Z(doms) {
var len = doms.length
for (var i = 0; i < len; i++) {
this[i] = doms[i]
}
this.length = doms.length
}
zepto.Z = function(doms) {
return new Z(doms)
}
zepto.init = function(doms) {
var doms = ['domObj1','domObj2','domObj3']
return zepto.Z(doms)
}
$ = function() {
return zepto.init()
}
$.fn = {
constructor: zepto.Z,
method: function() {
return this
}
}
zepto.Z.prototype = Z.prototype = $.fn
return $
在源碼中邓深,可以看出未桥, $
其實(shí)是一個(gè)函數(shù),同時(shí)在 $
身上又掛了很多屬性和方法(這里體現(xiàn)在 $.fn
身上芥备,其他的會(huì)在后續(xù)的文章中談到)冬耿。
我們?cè)谑褂?zepto 的時(shí)候,會(huì)用 $
去獲取 dom
门躯,并且在這些 dom
對(duì)象身上都有 zepto 定義的各種各樣的操作方法淆党。
從上面的偽代碼中,可以看到讶凉,$
其實(shí)調(diào)用了 zepto.init()
方法染乌,在 init
方法中,會(huì)獲取到 dom
元素集合懂讯,然后將集合交由 zepto.Z()
方法處理荷憋,而 zepto.Z
方法返回的是函數(shù) Z
的一個(gè)實(shí)例。
函數(shù) Z
會(huì)將 doms
展開(kāi)褐望,變成實(shí)例的屬性勒庄,key
為對(duì)應(yīng) domObj
的索引, 并且設(shè)置實(shí)例的 length
屬性瘫里。
zepto.Z.prototype = Z.prototype = $.fn
讀到這里实蔽,你可能會(huì)有點(diǎn)疑惑,$
最終返回的是 Z
函數(shù)的實(shí)例谨读,但是 Z
函數(shù)明明沒(méi)有 dom
的操作方法啊局装,這些操作方法都定義在 $.fn
身上,為什么 $
可以調(diào)用這些方法呢劳殖?
其實(shí)關(guān)鍵在于這句代碼 Z.prototype = $.fn
铐尚,這句代碼將 Z
的 prototype
指向 $.fn
,這樣哆姻,Z
的實(shí)例就繼承了 $.fn
的方法宣增。
既然這樣就已經(jīng)讓 Z
的實(shí)例繼承了 $.fn
的方法,那 zepto.Z.prototype = $.fn
又是為什么呢矛缨?
如果我們?cè)倏丛创a爹脾,會(huì)發(fā)現(xiàn)有這樣的一個(gè)方法:
zepto.isZ = function(object) {
return object instanceof zepto.Z
}
這個(gè)方法是用來(lái)判讀一個(gè)對(duì)象是否為 zepto 對(duì)象,這是通過(guò)判斷這個(gè)對(duì)象是否為 zepto.Z
的實(shí)例來(lái)完成的箕昭,因此需要將 zepto.Z
和 Z
的 prototype
指向同一個(gè)對(duì)象誉简。 isZ
方法會(huì)在 init
中用到,后面也會(huì)介紹盟广。
參考
最后闷串,所有文章都會(huì)同步發(fā)送到微信公眾號(hào)上,歡迎關(guān)注,歡迎提意見(jiàn):