这篇文章可以说是读这篇文章这篇文章后的总结。
jQuery最基本的构成结构:
var jQuery = window.jQuery = window.$ = function(a,b){
return new jQuery.fn.init(a, b); // 1
};
jQuery.fn = jQuery.prototype = {
init: function (s) {
this[0] = s;
this.length = 1;
this.context = s;
return this; // 2
},
age: function () {
return this;
}
};
jQuery.fn.init.prototype = jQuery.fn; // 3
jQuery.extend = jQuery.fn.extend = function () {
// 4
}
这是jQuery源码一个最基本的概要实现,但从这个实现中已经能弄并学到很多东西了。
( 1 ) 首先 $
也就是 jQuery
本身是一个函数, 但它又不是一个普通的构造函数,这从 $('div')
的这种实例直接产生不需要 new
就可以知道,也就是它隐藏了实例 new
的过程, jQuery
自身只是一个工厂函数,它产出由它的原型上定义的 init
方法的实例,因为拥有了 new
的过程,所以实例化中的 this
都是指向了 最终产生的实例本身,于是这样便实现了无new构建。
( 2 ) 这里在 init
函数中有一个 return this;
的操作,一般构造函数不会这样写,但这样写并不会影响 new 的结果,这参照之前new 的分解,便可以推出结果的一致( 只是返回了不同但值相同的变量 )。而jQuery之所以在这里要返回 this
是有用处的,这样最开始实例的 this
便得以保存,$('div').ready()
这样的链式调用便能得到前方的实例对象,也就是说就是 return this;
实现了链式调用。
( 3 ) 那既然是原型上的 init
构造器方法构建的实例,又怎么能获取到 jQuery
的原型方法呢,这就需要将 init 方法的原型用 jQuery
的原型对象覆盖。也就是 3 部分的操作。
( 4 ) 最后 $.extend
与 $.fn.extend
之所以会不一样,只是调用时分别是jQuery
对象或jQuery.prototype
(jQuery.prototype = jQuery.fn)导致了 this
的不同,实际定义是是用的同一个函数。