在解析jQuery實現機理之前,我們先總結一下幾點知識,這些都是我學習路上遇到的坑,我跌倒過很多次,現在把它補上:
1)自定義構造函數,如下例:
function person(){ this.name="aa"; } person(); console.log(window.name);//aa
這個函數是為了證明全局環境下的執行上下文是window(全局)對象,如上例無意間會創建一個全局變量name,因為this指向window對象。其實不通過new構造,執行函數內部的“this.屬性”會成為其父級對象域內的屬性;通過new構造,函數執行上下文會變成一個空的上下文,這個上下文代表了新生成的實例。總言之,this指向當前調用它的對象,更精確地說,this指向它的執行上下文。
2)利用對象[基本數據類型]格式創建的屬性只能通過對象[基本數據類型]的格式訪問;
3)在函數的內部有函數定義時為了避免this指針的指向混亂,在首函數的內部聲明"var self=this;",用self來表示此函數的this指針,避免與其他函數內部this指針混淆;
現在來看jQuery的實現機制:
以下是jQuery1.61內的代碼:
var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); }, ... class2type = {}; jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function(selector, context, rootjQuery){ } } // Give the init function the jQuery prototype for later instantiation jQuery.fn.init.prototype = jQuery.fn;
提煉總結上面這段代碼:jQuery.fn.init是個構造函數,因為jQuery.fn.init.prototype=jQuery.prototype,所以jQuery.fn.init的實例對象也是jQuery的實例對象,意指jQuery.fn.init構造的實例對象,可以訪問jQuery.fn.init.prototype的屬性及函數,也可以訪問jQuery.prototype的屬性及函數。
現在我們來遵循這個思路寫上這樣的代碼:
//創建一個jquery構造函數 function jQuery(selector){ return new jQuery.fn.init(selector); //返回一個jQuery對象,可以訪問jQuery.fn.init.prototype與jQuery.prototype中屬性 } //添加一個init函數給jQuery.fn jQuery.fn=jQuery.prototype={ constructor:jQuery, init:function(selector){ //通過init構造函數可以保持生產選取到dom節點的對象 if(selector==="undefined"){this.length=0;return this;}//未選擇 if(selector.nodeType==1){this[0]=selector;}else{this[0]=document.getElementById(selector);} //這裡this[0]指創建此jQuery實例對象的屬性0,且訪問格式只能是此jQuery對象[0] this.length=1; //給jQuery對象添加一個length屬性 }, css:function(name,value){ this[0].style[name]=value; return this; //鏈式調用 ,這裡this指css()的調用者--jquery的實例對象,而不是css構造出來的實例對象,返回jQuery對象 }, hide:function(){ var self=this; setTimeout(function(){ self[0].style.display="none"; //self[0]為選取的Dom節點對象 },2000); return this; //鏈式調用,通過jQuery原型的實例對象獲取 }, float:function(position){ this[0].style.float=position; return this; //鏈式調用,返回此時調用的jQuery對象 } } //將jQuery原型賦給jQuery.fn.init的原型,讓init可以生產jQuery的實例 jQuery.fn.init.prototype=jQuery.prototype;
我的注釋寫的可能有些亂,但作為學習的資料,我希望寫的詳細一點,通過我的注釋和你的思考,我相信理解起來並不困難。
需要說明的是,我這段代碼只能實現對有id標簽的元素的選取,並提供了改變位置和隱藏以及改變css樣式的功能,下面用一段代碼測試:
<p id="qq">234</p> <script type="text/javascript"> jQuery("qq").float("right").hide(); </script>
我這裡,功能完全可以實現,不知道你的怎麼樣,如果有啥問題,你可以給我留言。