2012-01-09 21 views
8

我收到了關於jQuery架構的另一個問題。 $('div')構造一個新jQuery對象:爲什麼可以像查詢數組一樣查詢jQuery('div')?

$('div') instanceof jQuery; // true 

我想知道爲什麼它是可以查詢它像一個數組,allthough它不是一個數組?

$('div')[0]; // returns the first div in the document as a DOM node. 
$.isArray($('div')); // false 

我只是喜歡這種語法,它看起來很乾淨!我也注意到了這個返回DOM節點作爲數組:

console.log($('div')); 

有人可以解釋我如何實現這種行爲我自己的對象?


我自己的方法是使一些方法,像這樣的數組:

var a = ['a', 'b', 'c']; 
a.method = function(){ return 'test'; }; 
a; // ['a', 'b', 'c'] 
a[0]; // 'a' 
a.method(); // 'test' 

然而,這似乎並沒有被jQuery不會的方式,因爲這實際上是一個數組:

$.isArray(a); // true 

我想知道jQuery如何做到這一點學習,看看它是否比我更好的解決方案。

+0

可以使用'[]'符號訪問* *的任何財產。不僅僅是指數。所以就像'$('div')[0]'一樣,你可以執行$('div')['jquery']',這會給你jQuery的版本號。 – 2012-01-09 18:14:10

+0

@amnotiam我知道。但是當我在控制檯中打印常用對象時,它們不輸出數組。 – 2012-01-09 18:14:53

+0

啊,如果你特別要求控制檯的輸出,那麼它確實就是控制檯對你輸入的內容做出最好的猜測。 [jAndy的回答](http://stackoverflow.com/a/8793090/1106925)顯示了控制檯通常會做什麼。 – 2012-01-09 18:16:36

回答

10

jQuery對象就是我們所說的Array-like object。這意味着,它確實是一個「真正的」對象(事實上,所有的「數組」都是ECMAscript中的對象),但它擁有某些使它看起來像一個「真實」數組的屬性。這些屬性

  • 它作爲.length財產
  • 它擁有.splice()方法

這兩個事實足以大多數 JS引擎 控制檯將interpretate對象作爲數組。

var myObject = { }, 
    push = Array.prototype.push; 

myObject.aNiceFunction = function() { 
    console.log(this); 
}; 

push.call(myObject, document.getElementById('foo')); 
push.call(myObject, document.getElementById('bar')); 

myObject.splice = Array.prototype.splice; 

如果我們現在登錄我們的對象

console.log(myObject); 

我們得到的典型jQuery'ish導致

[div#foo, div#bar] 

See that in action

但我們仍然可以在該對象上調用我們的方法.aNiceFunction()。通過將Array.prototype.push()方法推向新的元素到我們的對象上,ECMAscript會自動爲我們編制這些元素的索引。這是簡短的描述在jQuery引擎下發生了什麼。

關於ECMAscript中「陣列」的更多詞彙。這種語言沒有真正的數組(如果我們忘記typed arrays一秒鐘)。只有Object。如果我們有一個從Array.prototype繼承的對象,我們幾乎可以稱它爲一個數組。我們將要做的所有事情是,將.length屬性設置爲0

+2

JS引擎不會將任何內容解釋爲數組。 JS _users_將數據解釋爲數組。 :) – SLaks 2012-01-09 18:10:52

+0

@SLaks:touchè。我的意思是,它是如何被控制檯對象「註銷」的。 – jAndy 2012-01-09 18:17:52

+0

這是Firebug/Chrome漂亮打印機(它是JS用戶)的功能,而不是JS引擎。 – SLaks 2012-01-09 18:18:32

2

jQuery對象是類似數組的對象。

類似數組的對象是與數組具有相同屬性的普通對象。
狀物體的陣列具有length屬性設置爲正整數,和屬性命名01,... length − 1包含數組對象。

0

jQuery對象是「類似數組」的對象。考慮下面的代碼:

document.forms.length; // returns 1; 
document.forms[0]; // returns a form element. 
document.forms.join(", "); // throws a type error. this is not an array. 
typeof document.forms; // returns "object" 

修改你的代碼,你可以做到這一點同樣影響:

var a = 
{ 
    0: 'a', 
    1: 'b', 
    2: 'c', 
    length: 3, 
    method: function() { 
     return "test"; 
    } 
}; 
+0

'console.log(a)'不打印數組。所以這看起來並不像jQuery那樣。順便說一句,我不是JavaScript初學者,我知道JavaScript對象是如何工作的。 – 2012-01-09 18:18:01

1

像對待一個數組jQuery對象是鴨打字的應用程序。 From Wikipedia

在計算機編程用的面向對象的編程語言, 鴨打字動態類型的風格,其中對象的當前 集的方法和屬性來確定有效的語義,而 不是從它的繼承特定類別或特定接口的實現。

換句話說,這不是重要的是,jQuery函數實際上返回一個數組實例,只要它提供了必要的性能(例如length,數字索引)和方法行爲像陣列。

JavaScript有其他數組式樣對象。例如,arguments對象也不是數組,但它具有允許您假裝它的屬性(如length)。

0

我不確定這個「陣列式」的瘋狂是來自其他答案。 「陣列式」沒有標準術語。

這裏的實際區別是實際的數組,它是一個元素集合與一個鏈接列表(它是一個引用集合)的差異。在參考DOM時,鏈接列表被適當地稱爲節點列表。這些articlea有更多的信息:

http://www.mindcracker.com/Story/1016/interview-question-difference-between-linked-list-and-array.aspx

http://www.sitepoint.com/a-collection-is-not-an-array/

http://blog.duruk.net/2011/06/19/nodelists-and-arrays-in-javascript/