文章由来:jQuery源码学习时的总结
在JS中,一般的面向对象的写法如下:
function Cao(){}//定义一个构造函数 Cao.prototype.init = function(){}//原型上添加初始化方法 Cao.prototype.other = function(){}//可执行的其他实际方法 var c1 = new Cao();//实例化对象 c1.init();//初始化 c1.css();//操作函数
定义一个对象Cao,实例化c1,c1.init()初始化,c1.other()调用其他可用方法,这样的做法比较麻烦,每次调用都需要实例化c1,然后初始化c1.init(),最后才可以调用其他方法。
jQuery的做法是:
function jQuery(){return new jQuery.prototype.init();} jQuery.prototype.init = function(){} jQuery.prototype.other = function(){} jQuery.prototype.init.prototype = jQuery.prototype;//这句话可以先忽略,下面会讲 jQuery().other();
只有一行
jQuery().other();
代码就完成了所有工作,为什么?
分析下:
调用jQuery(),实际上完成了实例化和初始化的过程,因为jQuery()返回jQuery.prototype.init()的初始化对象。
jQuery->jQuery.prototype
jQuery->jQuery.prototype->jQuery.prototype.init
像上面的关系那样,返回的 new jQuery.prototype.init(),在jQuery的原型上,jQuery.prototype.init()上根本没有other()方法,如何让jQuery.prototype.init()也能操作other()呢?
所以就有了这样一句话:
jQuery.prototype.init.prototype = jQuery.prototype;
这句话是把jQuery原型的引用赋值给jQuery.prototype.init原型,像下面所示:
jQuery->jQuery.prototype
jQuery->jQuery.prototype->jQuery.prototype.init->jQuery.prototype.init.prototype->jQuery.prototype
这样在jQuery.prototype.init的原型上就有了jQuery原型的引用。
那jQuery()返回的jQuery.prototype.init(),实际上就包含了jQuery对象上的所有内容,所以jQuery().other();就是直接操作jQuery对象上的other()。
修改jQuery原型就是在修改初始化init对象的原型。
jQuery源码中实际的写法:
#61-#64行:
jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); },
jQuery.fn.init是什么鬼呢?
在#96有这么一句话:
jQuery.fn = jQuery.prototype = {...}
说明jQuery.fn就是jQuery.prototype,即jQuery原型。
在#283:
jQuery.fn.init.prototype = jQuery.fn;
就是jQuery.prototype.init.prototype = jQuery.prototype;