首頁 >web前端 >js教程 >jQuery內部原理與實作方式淺析_jquery

jQuery內部原理與實作方式淺析_jquery

WBOY
WBOY原創
2016-05-16 16:16:031124瀏覽

這段時間在學習研究jQuery源碼,受益於jQuery日益發展強大,研究jQuery的大牛越來越多,學習的資料也比前兩年好找了,有很多非常不錯的資源,如高雲的jQuery1.6.1源碼分析系列。這些教程非常細緻的分析了jQuery內部原理和實作方式,對學習和理解jQuery有非常大的幫助。但是個人認為很多教程對jQuery的整體結果把握不足,本人試圖從整體來闡述jQuery的內部實現。

大家知道,呼叫jQuery有兩種方式,一種是高階的實現,透過傳遞一個參數實現DOM選擇,如透過$(“h1″)選擇所有的h1元素,第二種是較為低階的實現,如果透過$.ajax實現ajax的操作。那麼,這兩種方式到底有何不同呢?用typeof函數檢測$('h1′)和$.ajax,類型分別為object和function,稍微學過jQuery的都知道或者聽過過,前者返回的是一個jQuery對象,那麼jQuery對像是什麼,它和jQuery是什麼關係呢?我們先來透過for(var i in $(”)) document.write(i ” :::” $(“”)[i] ””);列印一下jQuery物件的屬性和對應的值,可以看到它有100多個屬性,透過console輸入$(“*”)可以看到大部分屬性是繼承自jQuery原型的屬性,jQuery物件其實是這樣一個物件:

所以我們來推測,jQuery的實作可能是類似這樣的:

function jQuery(){
 this[0]="Some DOM Element";
 this[1]="Some DOM Element";
 this[2]="Some DOM Element";
 this.length=3;
 this.prevObject="Some Object";
 this.context="Some Object";
 this.selector="Some selector";
}
jQuery.prototype={
get:function(){},
each:function(){},
......
}

這些程式碼透過new運算子就可以建立出擁有上述屬性的jQuery物件,但是實際上我們呼叫jQuery建立jQuery物件時並沒有使用new運算符,這是如何實現的呢?來看jQuery的實作:

var jQuery = function( selector, context ) {
 // The jQuery object is actually just the init constructor 'enhanced'
 return new jQuery.fn.init( selector, context, rootjQuery );
}
jQuery.fn=jQuery.prototype={
 jquery: core_version,
 init:function(selector,context){
 //some code
 return this;
 }
 //some code there
 //......
}
jQuery.fn.init.prototype=jQuery.fn;

這裡有幾點做得非常巧妙的地方,第一點是透過jQuery原型屬性的init方法來創建物件來達到不用new創建物件的目的,第二點是對init方法內this指向的處理。我們知道,透過呼叫init傳回一個jQuery的實例,那麼這個實例就必須要繼承jQuery.prototype的屬性,那麼init裡面這個this, 就繼承jQuery.prototype的屬性。但是init裡面的this,受制於作用域的限制,並不能訪問jQuery.prototype其它的屬性,jQuery通過一句'jQuery.fn.init.prototype=jQuery.fn'把它的原型指向jQuery.fn,這樣以來,init產生的jQuery物件就擁有了jQuery.fn的屬性。

到這裡,一個jQuery的基本原型就浮出水面了。這裡有兩個對象,一個是jQuery這個建構函數,另外一個是這個建構子產生的對象(我們稱之為jQuery對象,它和普通對象沒有什麼差別), 如下關係圖:

可以看到jQuery建構函式和jQuery.prototype都有各自的屬性和方法,兩者的呼叫方法各不一樣,這兩個物件都有一個extend方法,都是用來擴充自身的屬性和方法,在jQuery內部,extend的實作實際上是靠一樣的程式碼, 將在後面的源碼分析中做以詳細的分析。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn