jQuery源码分析 开篇(一)
解读一个开源框架,最终目的当然就是学习程序的设计思想和实现技巧。
JavaScript宗旨就是Write Less, Do More,简洁的API,优雅的链式,强大的查询与便捷的操作都是我们喜欢他的原因。作为开发人员在使用jQuery时,由于仅仅只知道jQuery文档中的使用方法,不明白jQuery的运行原理,时常会碰到许多的问题。这些问题大部分是使用不当而产生,极少数是jQuery的Bug。因此如果我们只知道使用jQuery,而不知道其原理,那就是“知其然,而不知其所以然”,不明白其中运行机理和核心源码,我们也很难写出基于jQuery类库的高性能的程序出来。
jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我尽量按照这样的顺序去学习:
1. 读官方文档,官方有非常详细的文档说明
2. 读源码,加注释,把自己思考的过程和结果记录下来
3. 大量阅读相关的网文和书籍,比如相同主题的分析文档,网上常问的问题等
不管怎么说写一篇源码分析,记录自己的心得,加深理解,对我们来说好处不言而语。
好吧,废话不多说,开始解读(基于 jQuery 1.11 版本)。有分析或者语言表达不到位之处请指正(文笔一般)^^。
分析源码:首先要看懂这个(自调用匿名函数)
任何库和框架的设计,第一个要解决的问题就是命名空间与变量污染的问题。jQuery恰好利用到了javascript的函数作用域的特性,采用IIFE立即调用表达式包裹自身的方式来解决这个问题。
(function( window, undefined ) {
})(window,void 0);
通过定义这样一个匿名函数,创建了一个“私有”的命名空间,该命名空间的变量和方法,不会破坏全局的命名空间。如果将匿名函数返回值(函数)赋予func,并且返回值调用匿名函数作用域上的变量,该局部变量在函数这行完之后空间不会被释放。
var func = (function( window, undefined ) {
var i = 0
return function(){
console.log(i++);
}
})(window,void 0);
多次运行func(),你会发现i实现了自加功能。
这样确保jQuery创建的变量不能和导入的其他程序所使用的变量发生冲突,这也是jquery兼容性强大原因之一。
从jQuery各个版本来看,jQuery立即调用函数表达式使用有三种写法:
/*第一种:*/
(function(global,factory){
factory(global)
})(this,function(){
return function(){
//jQuery 实现
}
}) /*第二种:*/
var factory = function(){
return function(){
//jQuery 实现
}
}() var jQuery = factory();
/*
这种模式类似工厂模式,只是创建了一个单例
*/ /*第三种:*/
(function(window,undefined){
var jQuery = function(){
}
window.jQuery = window.$ = jQuery;
})(window) /* 这种写法的优势在于:
1、window和undefined都是为了减少变量查找所经过的scope作用域。当window通过传递给闭包内部之后,在闭包内部使用它的时候,可以把它当成一个局部变量
2、undefined也是同样的道理,其实这个undefined并不是JavaScript数据类型的undefined,而是一个普普通通的变量名。只是因为没给它传递值,它的值就是undefined,undefined并不是JavaScript的保留字
*/
对比写法1和写法3,写法3 利用写法1思想,把整个函数作为参数传递给另外一个函数,这样做的目的是主要是判断jQuery在不同平台下的加载逻辑。
当前的主流库一般都提供了对AMD和CMD的支持。jQuery也不例外,来看看代码的实现。
(function( global, factory ) {
if ( typeof module === "object" && typeof module.exports === "object" ) {//判断是否模块化引入jQuery 支持CMD规范
module.exports = global.document ?
factory( global, true ) :
function( w ) {
if ( !w.document ) {
throw new Error( "jQuery requires a window with a document" );
}
return factory( w );
};
} else if("function" == typeof define && define.amd) { //支持 AMD
define([],factory)
}else {
factory( global );
}
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
//省略jQuery实现
return jQuery;
})
接下来看看jQuery自调用匿名函数中都实现了什么功能,按照代码顺序做下排列:
(function( window, undefined ) { var jQuery = function( selector, context ) {//构建jquery对象
return new jQuery.fn.init( selector, context, rootjQuery );
}
// 工具函数 Utilities
// 异步队列 Deferred
// 浏览器测试 Support
// 数据缓存 Data
// 队列 queue
// 属性操作 Attribute
// 事件处理 Event
// 选择器 Sizzle
// DOM遍历
// DOM操作
// CSS操作
// 异步请求 Ajax
// 动画 FX
window.jQuery = window.$ = jQuery;
})(window);
以上注释清晰的展现了jQuery大致结构,有了这个结构框架,就能看懂jquery能做什么(结合jQuery文档,很容易就上手)。
jQuery一共13个模块,从2.1版开始jQuery支持通过AMD模块划分,这里面各个模块也不是单一的,比如jQuery动画,都会依赖异步队列、动画队列、回调队列与数据缓存模块等。
jQuery抽出了所有可复用的特性,分离出单一模块,通过组合的用法,不管在设计思路与实现手法上jQuery都是非常高明的(这里模块化思想值得我们借鉴与学习)
任何程序代码不是一开始就复杂的,成功也不是一躇而蹴的。接下来章节就来分解jQuery内部各个模块,探讨各个模块功能与实现。坚持^^
jQuery源码分析 开篇(一)的更多相关文章
- jQuery源码分析系列
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...
- [转] jQuery源码分析-如何做jQuery源码分析
jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...
- jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)
在第一篇jQuery源码分析中,简单分析了jQuery对象的构造过程,里面提到了jQuery.fn.jQuery.prototype.jQuery.fn.init.prototype的关系. 从代码中 ...
- [转]jQuery源码分析系列
文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...
- jquery源码分析之一前言篇
1.问:jquery源码分析的版本是什么? 答:v3.2.1 2.问:为什么要分析jquery源码? 答:javascript是一切js框架的基础,jquery.es6.vue.angular.rea ...
- jQuery源码分析-each函数
本文部分截取自且行且思 jQuery.each方法用于遍历一个数组或对象,并对当前遍历的元素进行处理,在jQuery使用的频率非常大,下面就这个函数做了详细讲解: 复制代码代码 /*! * jQuer ...
- jQuery源码分析系列(转载来源Aaron.)
声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...
- jQuery源码分析系列——来自Aaron
jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...
- jQuery源码分析系列(36) : Ajax - 类型转化器
什么是类型转化器? jQuery支持不同格式的数据返回形式,比如dataType为 xml, json,jsonp,script, or html 但是浏览器的XMLHttpRequest对象对数据的 ...
随机推荐
- python 002 文件输入输出
python 文件对象不仅可以访问普通磁盘文件,也可以访问抽象层面上的文件对象(例如URL地址) 打开文件open() file()功能一致可以任意替代 fp = open('/etc/test.tx ...
- 替换文件里的相关单词(一)之文件类型为txt
首先说一下详细的实现思路: 第一步:我们须要获取要改动文件的信息,我们能够通过文件的路径来获取文件的FileInputStream,即文件的输入流,然后调用InputStreamReader读取文件输 ...
- Codeforces Round #277 (Div. 2) D. Valid Sets DP
D. Valid Sets As you know, an undirected connected graph with n nodes and n - 1 edges is called a ...
- ⭐linux主次设备号介绍
1.主设备号与次设备号的功能 在Linux内核中,主设备号标识设备对应的驱动程序,告诉Linux内核使用哪一个驱动程序为该设备(也就是/dev下的设备文件)服务:而次设备号则用来标识具体且唯一的某个设 ...
- 学习笔记二十三——字符函数库cctype【转】
本文转载自: 字符函数库cctype 在头文件cctype(ctype.h)中定义了一些函数原型,可以简化输入确定字符是否为大写字母.数字.标点符号等工作. 例如: 如果ch是一个字母,则isalph ...
- iOS版本、iPhone版本、Xcode版本比对
iOS版本 iPhone版本 Xcode版本 其他 2003年 Xcode1.0 2005年4月29日 Xcode2.0 2007年1月9日 iPhone OS(iOS1): 虚拟键盘.谷歌地图 第一 ...
- php的string编码类型
在php中字符编码转换我们一般会用到iconv与mb_convert_encoding进行操作,但是mb_convert_encoding在转换性能上比iconv要差很多哦.string iconv ...
- go之数据类型转换和类型断言
一.类型转换 1.1 简单类型转换 格式 valueOfTypeB = typeB(valueOfTypeA) int 转 float64 package main import "fmt& ...
- B - Chat room
Problem description Vasya has recently learned to type and log on to the Internet. He immediately en ...
- webApi上传服务,可重命名,可创建文件夹
webApi上传服务,根据FileName重命名,根据Path创建文件夹 /// <summary> /// 上传文件 /// </summary> /// <retur ...