文章由來: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;
