近日不用学习java代码,特此来回忆一下javascript部分,学习了如何去阅读源代码,并从中有了不少的心得,现在在博客上分章节记录zepto的源码分析。 zepto.js我想现在应该很少会用到它,我们大部分的框架是jquery,react,vue,AngularJS ,但是这里面的框架代码都太多了,是相对大的框架,而我现在自学阅读的zepto是一个轻量级的针对现代高级浏览器的javascript库,代码也就1000行左右,他有着和jquery类似的api,可是jquery大概是9211行(2.1.4版本),所以如果你会用jquery,那你也一定是会会用zepto的啦。
读一个源代码,你可能不会记得他的每一个部分都是怎么实现的所以你要懂得的就是他的设计体系,设计思想。
首先先简单的介绍一下zepto的模块:
module default description zepto ✔ 核心模块;包含许多方法 event ✔ 通过on()
& off()
处理事件 ajax ✔ XMLHttpRequest 和 JSONP 实用功能 form ✔ 序列化 & 提交web表单 ie ✔ 增加支持桌面的Internet Explorer 10+和Windows Phone 8。
这个是api中的default的部分,相对重要的就是core的部分。有需要的请自行阅读api;
var Zepto=(function(){...})()
window.Zepto=Zepto
window.$===undefined&&(window.$=Zepto)
这个是zepto源代码中我们需要理解的主要大框:
首先是先定义了一个Zepto让她等于一个自运行函数,函数里面的内容可以暂时不看,之后又写了两个赋值,一直到这两行结束,core的代码就结束了。现在我们来分析一下从3-882行的
var Zepto=(function(){...})()
这里面先说一嘴为什么要把Zepto函数包起来?因为这样可以有效的减少全局污染,这是对变量的一种封装,就是有作用域的问题,具体深入的可以百度有关文章(我现在一直都很小心Zepto的开头大写部分,因为在下面的函数中有一个小写的zepto即将定义):
var Zepto=(function(){
var $
//一堆代码
$=function(selector,context){
return zepto.init(selector,context)
}
return $
})()
在代码中大体是定义了一个$变量,让她等于一个有两个参数的函数,并返回调用了一个zepto.init函数,最后再一次返回$,其中的
zepto.init是一个双参数的,返回调用了zepto.z的函数:
其实zepto.init主要就是在有着双参数的函数中定义了一个dom,之后通过许多的代码判断来给dom赋值,最后返回一个zepto.z(dom,selector)zepto.init = function (selector, context) { var dom if (!selector) return zepto.Z() else if (typeof selector == 'string') { selector = selector.trim() if (selector[0] == '<' && fragmentRE.test(selector)) dom = zepto.fragment(selector, RegExp.$1, context), selector = null else if (context !== undefined) return $(context).find(selector) else dom = zepto.qsa(document, selector) } else if (isFunction(selector)) return $(document).ready(selector) else if (zepto.isZ(selector)) return selector else { if (isArray(selector)) dom = compact(selector) else if (isObject(selector)) dom = [selector], selector = null else if (fragmentRE.test(selector)) dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null // 及时清空 selector 不妨碍下面的判断 else if (context !== undefined) return $(context).find(selector) else dom = zepto.qsa(document, selector) } return zepto.Z(dom, selector) }
其中的fragmentRE = /^\s*<(\w+|!)[^>]*>/;
再要说的话就是zepto.z这个函数了,他有两个版本,分别是源代码中的和GitHub里面的,两者有着不小的区别。
在源码中:
zepto.Z = function(dom, selector) { dom = dom || [] dom.__proto__ = $.fn dom.selector = selector || '' return dom }在GitHu里面的是:
function z(dom,selector){ var i,len=dom?dom.length:0; for(i=0;i<len;i++)this[i]=dom[i] this.length=len; this.selector=selector||'' } Zepto.z=function (dom,selector) { return new z(dom,selector) } Zepto.z.prototype=z.prototype=$.fn在GitHub中多了一个z,最后操作的时候也是有一个原型赋值的部分。其中的$.fn是一个有着很多属性的对象,具体可在源码中查看。现在大概说明了zepto查看的基本的方法,之后的文章中我会写出每一部分我自己的一些理解。这是后面部分的图片,格式实在是调不好了