解读一个开源框架,最终目的当然就是学习程序的设计思想和实现技巧。

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源码分析 开篇(一)的更多相关文章

  1. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  2. [转] jQuery源码分析-如何做jQuery源码分析

    jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...

  3. jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)

    在第一篇jQuery源码分析中,简单分析了jQuery对象的构造过程,里面提到了jQuery.fn.jQuery.prototype.jQuery.fn.init.prototype的关系. 从代码中 ...

  4. [转]jQuery源码分析系列

    文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...

  5. jquery源码分析之一前言篇

    1.问:jquery源码分析的版本是什么? 答:v3.2.1 2.问:为什么要分析jquery源码? 答:javascript是一切js框架的基础,jquery.es6.vue.angular.rea ...

  6. jQuery源码分析-each函数

    本文部分截取自且行且思 jQuery.each方法用于遍历一个数组或对象,并对当前遍历的元素进行处理,在jQuery使用的频率非常大,下面就这个函数做了详细讲解: 复制代码代码 /*! * jQuer ...

  7. jQuery源码分析系列(转载来源Aaron.)

    声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...

  8. jQuery源码分析系列——来自Aaron

    jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...

  9. jQuery源码分析系列(36) : Ajax - 类型转化器

    什么是类型转化器? jQuery支持不同格式的数据返回形式,比如dataType为 xml, json,jsonp,script, or html 但是浏览器的XMLHttpRequest对象对数据的 ...

随机推荐

  1. hdu4738Caocao's Bridges

    什么?有人要炸我的桥?!D飞他(心疼周瑜大都督) 这个就是求割边/桥了. #include<cstdio> #include<iostream> #include<cst ...

  2. poj--1274--The Perfect Stall(匈牙利裸题)

    The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 21868   Accepted: 980 ...

  3. thinkphp session db配置

    这篇文章主要介绍了ThinkPHP实现将SESSION存入MYSQL的方法,需要的朋友可以参考下   本文以实例讲解了ThinkPHP实现将SESSION存入MYSQL的方法,所采用的运行环境是Thi ...

  4. 安装robotframework-ride

    先安装好python并配置好环境变量 1.Windows+r后输入CMD 安装robotframework框架 2.输入pip install robotframework 安装RIDE前需要安装的依 ...

  5. 使用Github做服务器展示前端页面

    1)在github上创建自己一个项目,项目名称必须是你的github账号名.github.io  譬如 fk123456.github.io 因为我已经创建了,所以显示名字重复. 2)使用命令行的方式 ...

  6. POJ 1523 Tarjan求割点

    SPF Description Consider the two networks shown below. Assuming that data moves around these network ...

  7. E - Perfect Number

    Problem description We consider a positive integer perfect, if and only if the sum of its digits is ...

  8. SDOI 2018 round2游记

    Day 0 早上起来从北京到济南 住宿环境不错 不过比赛环境怎么这么low啊 而且我在最偏僻的考场中最偏僻的角落里 身边居然是个妹子?! Day1 7:40到的考试地点 发现诸位大佬已经打完板子了or ...

  9. list用法(用到了再补充)

    之前学list吧,也知道很多,但是到用的时候却无从下手,还是不熟悉的缘故,看来基础知识应该再加强,要达到信手拈来的程度才行. 先说下list的特性:有序可重复,也可以存储多个空值. 我用到的方法: L ...

  10. creat-react-app 支持 less

    yarn  eject yarn add less less-loader config/ webpack.config.dev.js config/ webpack.config.prod.js 文 ...