jQuery對象是一個類數組對象,它保存的是對應的DOM的引用,我們可以直接用[]獲取某個索引內的DOM節點,也可以用get方法獲取某個索引內的DOM節點,還可以用toArray()方法把jQuery對象一次性轉換成一個數組,例如: 將DOM對象轉換為jQuery對象就更方便了,直接放到jQuery ...
jQuery對象是一個類數組對象,它保存的是對應的DOM的引用,我們可以直接用[]獲取某個索引內的DOM節點,也可以用get方法獲取某個索引內的DOM節點,還可以用toArray()方法把jQuery對象一次性轉換成一個數組,例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script> </head> <body> <p>1</p> <p>2</p> <p>3</p> <script> var jObject = $('p'); console.log(jObject[0].innerHTML) //輸出:1 console.log(jObject[1].innerHTML) //輸出:2 console.log(jObject.get(2).innerHTML) //輸出:3 console.log(jObject.toArray()) //輸出:Array(3) [ p, p, p ] ;每個元素都是一個DOM節點,等於對應的p元素 </script> </body> </html>
將DOM對象轉換為jQuery對象就更方便了,直接放到jQuery的構造器內即可,如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script> </head> <body> <p>1</p> <p>2</p> <p>3</p> <script> var p = document.getElementsByTagName('p'), result = []; for(let i = 0;i<p.length;i++) result.push(i) //getElementsByTagName獲取的是HTMLCollection對象,也是個類數組,我們把它轉換為數組格式 console.log( $(p) instanceof $ ) //輸出true ;表示$(p)是一個jQuery對象 console.log( $(p).size() ) //輸出:3 ;因為p內有3個DOM元素 console.log( $(p[0]) instanceof $ ) //輸出true ;表示$(p)是一個jQuery對象 console.log( $(p[0]).size() ) //輸出:1 ;因為我們只傳入一個p[0],只有一個DOM節點 </script> </body> </html>
輸出如下:
原因在代碼里註釋得挺詳細了,嗯,就這樣
源碼分析
writer by:大沙漠 QQ:22969969
DOM轉換成jQuery對象都是在jQuery內部的init()函數內實現的,如下:
init: function( selector, context, rootjQuery ) { /*略*/ // Handle $(DOMElement) if ( selector.nodeType ) { //selector有屬性nodeType,則認為selector是DOM元素,例如:$(document.getELementById('d')) this.context = this[0] = selector; //保存該DOM節點的引用 this.length = 1; //設置length屬性為1 return this; //返回this,以支持鏈式操作 } /*略*/ return jQuery.makeArray( selector, this ); //這裡是最後的邏輯,如果selector是數組或偽數組 },
makeArray是jQuery內部的一個函數,用於把一個類數組轉換成真正的數據,如下:
makeArray: function( array, results ) { //將一個類數組對象轉換為真正的數組 var ret = results || []; //如果results不存在則修正為空數組,初始化jQuery執行到這裡時這裡的result等於jQuery對象,也就是上面傳進來的this if ( array != null ) { //過濾參數array是null、undefined的情況。 // The window, strings (and functions) also have 'length' // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 var type = jQuery.type( array ); if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { //如果array沒有屬性length 或者 參數array是字元串,或者是函數,或者是正則,或者是Window對象 push.call( ret, array ); //認為參數array不是數組,也不是類數組對象,調用數組方法push()把該參數插入返回值ret的末尾。 } else { jQuery.merge( ret, array ); //否則認為參數array是數組或類數組對象,調用方法jQuery.merge()把該參數合併到返回值ret中 } } return ret; },
最後返回該數組,因為我們在第二個參數傳遞了this,因此makeArray最後會返回this
對於jQuery對象轉換為DOM對象來說,由於jQuery本身就是個類數組對象,因此,我們可以直接用[]獲取索引,對於get和toArray方法來說,這些操作定義在jQuery的原型上,也就是jQuery.fn上的,如下:
jQuery.fn = jQuery.prototype = { //重寫jQueyr.fn /*略*/ toArray: function() { //將當前jQuery對象轉換為真正的數組,轉換後的數組包含了所有元素。 return slice.call( this, 0 ); }, get: function( num ) { //返回當前jQuery 對象中指定位置的元素或包含了全部元素的數組, return num == null ? // Return a 'clean' array this.toArray() : // Return just the object ( num < 0 ? this[ this.length + num ] : this[ num ] ); //直接返回this[num],也就是和我們用[]是一樣的,只是封裝了一下 }, /*略*/ }
我們可以看到對於get來說,就是直接從this[]上獲取的,而toArray則調用了數組了slice方法,將類數組轉換成真實的數組