前言
在学习的过程中,学会阅读源码也是一种很好的过程,但是对于一个新手来说,阅读源码就像一面茫然,下载了源码不知道从何开始.这里楼主选择从Zepto源码开始学习.首先因为Zepto并不复杂,Zepto实现功能还是比较简单, Zepto是类似于Jquery的轻量库,不过作用于手机端,类似于Jquery对DOM操作进行拼接,Zepto对PC端的IE浏览器兼容并没有做得很好,需然大小比Jquery小但是也没有Jquery做得那么好.
阅读源码需要具备什么条件
在阅读源码时需要准备些什么,你才能读懂:
在阅读源码之前你需要知道这个源码的功能和作用是什么?实现什么功能?越清楚你就越容易看懂.
在阅读源码之前你需要把源码的文档,或者测试用例看一次.
找到源码的入口,暴露在全局的入口.如果你找不准代码看起来就像一团乱麻,得找到线头入口.
读源码的时候需要,得先把源码的代码结构先弄清楚,细节的代码逻辑再慢慢整理.
从$入口开始分析
在你细细看过Zepto 文档后,基本发现Zepto都是通过$使用的.$是什么?在网页脚本中导入后,$是调用Zepto的入口,我们再详细查看一下Zepto下面的方法,如下图分成了两类:
1 |
|
区别在于核心方法是挂在$对象上面的,
另一个是挂在$()生成的对象上面的.
我们可以测试一下:
1 |
|
输出一下下面代码1
2
3console.log($.prototype);
console.log($("#title"));
console.log($);
你会发现这的确很大区别的
Zepto源码结构
在引入Zepto后,$是一个window的一个全局变量.
Zepto核心闭包与返回$
1 | var Zepto = (function() { |
zepto核心其实是一个立即执行的闭包对象,通过定义为一个对象,赋值给window.$, 这样不会污染全局环境,防止了包里面的方法和命名冲突.
我们可以看到最后把最后把$返回给Zepto对象,那在Zepto立刻执行方法里面的$是什么呢?下面我们来一步一步实现Zepto包最简单的架构,解释$是什么.
继续接上代码
定义$变量,交给zepto.init方法处理细节
1 | // 对全局暴露Zepto变量 |
添加zepto.init方法,添加zepto对象
1 | // 对全局暴露Zepto变量 |
添加Zepto.Z 处理dom
1 | // 对全局暴露Zepto变量 |
现在基本成型了,接下来我们要在$的构造方法上面添加方法
1 | // 定义$变量 |
添加原型链上的方法
1 |
|
最后我们这里添加了原型链方法,each empty html test,都是定义在$.fn
上面.当你调用$()
生成DOM之后会返回一个Z对象,就是在Z.prototype = $.fn
将$.fn
继承到Z对象上面的.
然之前定义的$.each()
是定义在$
核心构造方法上面的,两个调用的方式也不一样.
在Z.prototype = $.fn
继承后,为什么还要zepto.Z.prototype = Z.prototype
呢?
如果我们再看源码,会发现有这样的一个方法:1
2
3zepto.isZ = function(object) {
return object instanceof zepto.Z
}
这个方法是用来判读一个对象是否为 zepto 对象,这是通过判断这个对象是否为 zepto.Z 的实例来完成的,因此需要将 zepto.Z 和 Z 的 prototype 指向同一个对象。 isZ 方法会在 init 中用到。
现在可以把自己创造的zepto包导入到自己定义的网页当中.你会注意到刚才自己定义的方法已经可以使用了.
测试一下,没问题了.
$('#test').test()
下面看一下zepto结构的图: 转至wangfupeng博客图
在清楚大概程序答建结构后,就可以细看分支了,可以细看每一个方法是怎样实现的.
细节实现
当你观看细节方法功能实现的时候,看到的是不一样的东西,比如是JavaScript数组的处理,全局window对象的判断,原生JavaScript方法操作等,学到的东西是不一样的,值得细细学习,不过细节方法实现我不一一详解了,我看到另一作者写得很详细的,如果有兴趣的读者可以深入研究一下,下面给出相关作者连接:
作者 yeyuqiudeng
读 Zepto 源码,分析 Zepto 源码 连接