jquery源码学习(一)

从整体上看,jquery源码的学习主要分为这几部分:

  • 定义的一些变量和函数
  • 为jquery对象添加的一些方法和属性
  • extend:jquery的继承方法
  • jQuery.extent():扩展一些工具和方法
  • Sizzle:复杂选择器的实现
  • Callbacks:回调对象 对函数的管理
  • Deferred:延迟对象 对异步的管理
  • support:功能检测 判断浏览器版本
  • data():数据缓存
  • queue()、dequeue():队列管理
  • attr()、prop()、val()等:对元素属性的操作
  • on()、trigger()等:事件操作相关的方法
  • DOM操作:添加、删除、获取、包装、筛选等
  • css():样式的操作
  • 提交的数据和ajax():ajax相关
  • animate():运动相关
  • offset():位置方法,尺寸方法
  • jquery支持模块化的部分

jQuery.fn.init

源码中的片段(v2.1.4):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init( selector, context );
}

...

jQuery.fn = jQuery.prototype = {
// The current version of jQuery being used
jquery: version,

constructor: jQuery,

...
}

init = jQuery.fn.init = function( selector, context ) {

var match, elem;

...
}

init.prototype = jQuery.fn;

分析:

普通常用的面向对象的简单写法是:

1
2
3
4
5
6
7
8
9
10
function Demo() {}

Demo.prototype.init = function() {};

Demo.prototype.dosomething = function() {};

//调用
var demo = new Demo();
demo.init();
demo.dosomething();

而jquery中我们经常调用方法的方式是这样的:

1
jquery.css().hide();

那么如何改造上面常用的面向对象的写法呢?

1
2
3
4
5
6
7
8
9
10
function jQuery() {
return new jQuery.prototype.init();
}

jQuery.prototype.init = function() {};

jQuery.prototype.dosomething = function() {};

//调用
jQuery().dosomething();

由于构造函数中return了new jQuery.prototype.init(),相当于返回了new出来的一个对象,同时执行了init方法,那么就可以接着链式调用下一个方法dosomething()了。

当然只这么写还是有问题,看上面的源码片段中还有这么几句等价于下面的写法:

1
jQuery.fn.init.prototype = jQuery.fn;

源码中又定义了jQuery.fn = jQuery.prototype,那么上面的语句等价于

1
jQuery.prototype.init.prototype = jQuery.prototype;

把jquery的原型赋给了初始化函数的原型,那么上面jQuery().dosomething()的写法就合法了