初识jQuery源码

为了深入学习下jQuery,最近打算看看源码,刚开始看这个我内心其实是拒绝的。。。第一印象就是好难理解,没办法硬骨头总是要去啃得,看了好多分析源码的文章博客,第一篇当然是Aaron的jQuery源码解读系列的开篇之整体架构。介绍的还是比较详细的,推荐~当然要抱着怀疑的眼光去看,不一定人家写的就是对的,敲出来验证下才是王道,这篇文章后的评论也可以看看,是大家对于该文章某些地方的质疑。

看完这篇文章其实我是半懂的状态,后来又看到一篇总结的博文,大概是在此基础上总结的。

点这里

我并不想重复的记录下相同的文字,只是想说一下我理解的时候觉得困难的地方。

先附上源码:

1
2
3
4
5
6
7
8
9
10
11
12
jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
},
jQuery.fn = jQuery.prototype = { //fn即对应prototype
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
...
return this;
}
...
}
jQuery.fn.init.prototype = jQuery.fn;

1.jQuery中为什么要返回new jQuery.fn.init
首先为了让我们在调用jQuery的时候像这样:

1
2
$('#id').css();
$.ajax();

就是把jQuery看成是一个类,在原型上绑定方法就相当于成员方法,在jQuery上绑定工具方法,相当于类的静态方法,实例化之后就能直接调用这些方法了。
那要怎样才能返回一个实例呢,对 最容易想到的就是return new jQuery();
写完有没有发现什么不对的地方,var jQuery = function(selector, context) { return new jQuery();}这个方法陷入了死循环了。然后就把方法放到原型中去

1
2
3
4
5
6
7
8
9
10
11
12
jQuery = function( selector, context ) {
return jQuery.fn.init();
},
jQuery.fn = jQuery.prototype = {
init: function() {
this.name='Tom';
return this;
},
anotherName:'Mike'
};
console.log(jQuery().anotherName);//"Mike"
console.log(jQuery().name);//"Tom"

这样返回实例对象是解决了,但是this原本只指向jQuery类的,这里却指向了jQuery.fn;所以需要隔离出作用域出来。故返回的是new jQuery.fn.init();

但是这个时候,jQuery并不能调用jQuery.fn上的方法了。所以才有了这一句:
jQuery.fn.init.prototype = jQuery.fn;将init的原型指向jQuery.fn,也就是用jQuery的原型对象覆盖init的原型对象,因为JQ对象根本就是init函数的实例对象,console.log(jQuery() instanceof jQuery.prototype.init); //true;这样一来,jQuery就能调用jQuery.fn上的属性和方法了。

2.为什么为了避免全局污染的时候要传入第二个参数undefined

在参数列表中给出undefined,但是不传入值,那么就确保了函数内部undefined是自身的值。在ECMAScript5之前undefined都是可写的,也就是undefined可以赋值的。jQuery作者这么做的目的还有防止程序员对undefined进行赋值后使得代码出现了不可预料的bug。

以上就是个人结合各方博客对于初识源码中难点的理解,有不对的请指出,不胜感激~

附上两篇博文的链接:
http://www.cnblogs.com/aaronjs/p/3278578.html

http://www.cnblogs.com/SheilaSun/p/4779895.html