jQuery源码解析

jQuery2.0之后不再支持IE6/7/8,从2.1版开始jQuery支持通过AMD模块化分
jQuery的核心理念:The Write Less,Do More.
image
任何库与框架设计的第一个要点就是解决命名空间与变量污染的问题。jQuery就是利用了JavaScript函数作用域的特性,采用立即调用表达式包裹了自身的方法来解决这个问题。
jQuery兼容的具体策略:针对高级的浏览器,我们当前很乐意用DOMContentLoaded事件了,省时省力。
对于旧的IE,document.attachEvent
jQuery的整体架构:
变量、常用正则初始化
工具方法$.fn
$.ready()
复杂选择器Sizzle
回调对象:对函数的统一管理$.Callback()
延迟对象:对异步的统一管理$.Deferred()
浏览器功能性检测$.support
数据存储$.data
队列方法:执行顺序的管理queue()|dequeue()
对元素属性的操作:attr()、prop()、val()、addClass()等
事件操作的相关方法:on()、trigger()
DOM操作
样式操作:css()
Ajax()
动画animate()
位置和尺寸offset()
模块化
window.jQuery = window.$ = jQuery;
jQuery 闭包结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 用一个函数域包起来,就是所谓的沙箱
// 在这里边 var 定义的变量,属于这个函数域内的局部变量,避免污染全局
// 把当前沙箱需要的外部变量通过函数参数引入进来
// 只要保证参数对内提供的接口的一致性,你还可以随意替换传进来的这个参数
(function(window, undefined) {
// jQuery 代码
})(window);
jQuery 具体的实现,都被包含在了一个立即执行函数构造的闭包里面,为了不污染全局作用域,只在后面暴露 $ 和 jQuery 这 2 个变量给外界,尽量的避开变量冲突。
jQuery 在这里有一个针对压缩优化细节,使用这种书写方式,在代码压缩的时候,window 和 undefined 都可以压缩为 1 个字母并且确保它们就是 window 和 undefined。
// 压缩策略
// w -> windwow , u -> undefined
(function(w, u) {

})(window);

内部实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
jQuery = function(selector, context) {
// The jQuery object is actually just the init constructor 'enhanced'
// 看这里,实例化方法 jQuery() 实际上是调用了其拓展的原型方法 jQuery.fn.init
return new jQuery.fn.init(selector, context, rootjQuery);
},

// jQuery.prototype 即是 jQuery 的原型,挂载在上面的方法,即可让所有生成的 jQuery 对象使用
jQuery.fn = jQuery.prototype = {
// 实例化化方法,这个方法可以称作 jQuery 对象构造器
init: function(selector, context, rootjQuery) {
// ...
}
}
// 这一句很关键,也很绕
// jQuery 没有使用 new 运算符将 jQuery 实例化,而是直接调用其函数
// 要实现这样,那么 jQuery 就要看成一个类,且返回一个正确的实例
// 且实例还要能正确访问 jQuery 类原型上的属性与方法
// jQuery 的方式是通过原型传递解决问题,把 jQuery 的原型传递给jQuery.prototype.init.prototype
// 所以通过这个方法生成的实例 this 所指向的仍然是 jQuery.fn,所以能正确访问 jQuery 类原型上的属性与方法
jQuery.fn.init.prototype = jQuery.fn;