jQuery選擇器的工作理和優化分析

NO IMAGE

每次申明一個jQuery物件的時候,返回的是jQuery.prototype.init 物件,很多人就會不明白,init明明是jQuery.fn的方法啊,實際上這裡不是方法,而是init的建構函式,因為js的prototype物件可 以實現繼承,加上js的物件只是引用不會是拷貝,new jQuery,new jQuery.fn和new jQuery.fn.init的子物件是一樣的,只是有沒有執行到init的不同,這裡就不講原因了,等下一篇再講為什麼會是這樣。
當我們使用選擇器的時候$(selector,content),就會執行 init(selectot,content),我們看看inti中是怎樣執行的:
複製程式碼 程式碼如下:
if ( typeof selector == “string” ) {
//正則匹配,看是不是HTML程式碼或者是#id
var match = quickExpr.exec( selector );
//沒有作為待查詢的 DOM 元素集、文件或 jQuery 物件。
//selector是#id的形式
if ( match && (match[1] || !context) ) {
// HANDLE: $(html) -> $(array)
//HTML程式碼,呼叫clean補全HTML程式碼
if ( match[1] ){
selector = jQuery.clean( [ match[1] ], context );
}
// 是: $(“#id”)
else {
//判斷id的Dom是不是載入完成
var elem = document.getElementById( match[3] );
if ( elem ){
if ( elem.id != match[3] )
return jQuery().find( selector );
return jQuery( elem );//執行完畢return
}
selector = [];
}
//非id的形式.在context中或者是全文查詢
} else{
return jQuery( context ).find( selector );
}
}

這裡就說明只有選擇器寫成$(‘#id’)的時候最快,相當於執行了一次 getElementById,後邊的程式就不用再執行了。當然往往我們需要的選擇器並不是這麼簡單,比如我們需要id下的CSS為className, 有這樣的寫法$(‘#id.className’)和$(‘#id’).find(‘.className’);這兩種寫法的執行結果都是一樣的,比 如<div id=”id”><span class=”className”></span></div>,返回的肯定都是<span class=”className”></span>,但是執行的效率是完全不一樣的。
在分析一下上邊的程式碼,如果不是$(‘#id’)這樣的簡單選擇器的話,都會執行find函 數,那我們再看看find到底是做用的:
複製程式碼 程式碼如下:
find: function( selector ) {
//在當前的物件中查詢
var elems = jQuery.map(this, function(elem){
return jQuery.find( selector, elem );
});
//下邊的程式碼可以忽略,只是做一些處理
//這裡應用了js的正則物件的靜態方法test
//indexOf(“..”)需要了解一下xpath的語法,就是判斷selector中包含父節點的寫法
//本意就是過濾陣列的重複元素
return this.pushStack( /[^ >] [^ >]/.test( selector ) || selector.indexOf(“..”) > -1 ?
jQuery.unique( elems ) :
elems );
}

如果這樣寫$(‘#id .className’),就會執行到擴充套件的find(‘#id .className’,document),因為當前的this是document的jQuery陣列,那我們在看看擴充套件的find他的實現,程式碼比較 多,就不列出來,總之就是從第二個引數傳遞進行的dom第一個子節點開始找,遇見#比對id,遇見.比對ClassName,還有:< -等處理。 那我們要優化,是不是就要想辦法讓第二個引數context的範圍最小,那樣遍歷是不是就很少了?
如果我們這樣寫$(‘#id’).find(‘.className’),那程式只這樣執行 的,第一次init的時候執行一步getElementById,就return了,接著執行 find(‘.className’,divDocument),divDocument就是我們第一次選擇的是div標籤,如果document下有很 多dom物件的時候,這次只遍歷divDocument是不是少了很多次,而且在第一次選擇id的速度也要比遍歷快的多。
現在大家應該是明白了吧。就是說第一層選擇最好是ID,而是簡單選擇器,目的就是定義範圍, 提高速度,這次就說這些,選擇寫法的優化,其他的優化,下次再說。

您可能感興趣的文章:

jQuery原理系列-css選擇器的簡單實現jquery選擇器原理介紹($()使用方法)jQuery原始碼分析-04 選擇器-Sizzle-工作原理分析Jquery選擇器 $實現原理詳解jquery選擇器的原理