2011-10-04 99 views
6

起初我以爲它只是在返回之前將obj [0],obj [1],obj [2]等分配給jQuery對象,並且指定的長度爲,手動已分配。但是,不,因爲console.log記錄一個數組而不是一個對象。jQuery如何創建數組對象?

我快速瀏覽了jQuery源代碼,但由於我不熟悉它,所以我沒有輕易破解它。 jQuery.makeArray首先彈出,但事實證明與我正在尋找的相反,實際上通過使用它丟失了對象方法。

我的第一個猜測是首先啓動數組,然後將所有的屬性和方法從對象複製到它。

有沒有人有jQuery源代碼的經驗有明確的答案呢?

+0

它被認爲與'NodeList'工作方式類似於數組,但不是。 – BoltClock

+0

什麼是數組對象?你怎麼知道它記錄一個數組而不是一個對象? –

回答

5

這是爲創建一個新的功能,並分配一個新的數組作爲它的原型一樣簡單。

function ArrayLike() {} 
ArrayLike.prototype = []; 

因此,例如:

function ArrayLike() {} 
ArrayLike.prototype = []; 
ArrayLike.prototype.fromArray = function(arr) { 
    for(var i = 0; i < arr.length; i++) 
     this.push(arr[i]); 
}; 
ArrayLike.prototype.foo = function() { 
    console.log("foo", this); 
}; 

var a = new ArrayLike(); 
a.fromArray([1, 2]); 
console.log(a); 
a.foo(); 

http://jsfiddle.net/Xeon06/fUgaf/

+0

這是非常光滑的。我會問一個關於這個簡約版本的問題。謝謝。 – Manngo

13

jQuery創建所謂的(在ES標準中)類似數組的對象。特別是,他們有一個長度屬性,並且(使用長度屬性),他們有相關的項目放置在基於整數的索引下。

很簡單:

var arrayLike = {length: 3, 0:'first', 1:'second', 2:'third'}; 
Array.prototype.join.call(arrayLike, '|'); // "first|second|third" 

如果你看一看the standard(15.4.4),特別是Array.prototype方法,你會看到在每一個下面的註釋:

注* *函數是有意通用的;它不要求 它的這個值是一個Array對象。因此可以將其轉換爲其他類型的對象以用作方法。 *函數是否可以將 成功應用於主機對象取決於實現。

如果你看看這些算法的描述,他們幾乎只使用length屬性來遍歷對象(在我們的情況下,陣列狀對象)和訪問背後那些基於整數的值鍵。出於這個原因,它們是通用的,並且處理具有相關屬性的常規js對象。本質上,這就是所有的jQuery(如果我沒有記錯的話,建設是在嘶嘶聲,jQuery的css選擇器引擎完成)。你可以用多種方法來測試/證明它。例如,一個標準的js陣列執行一些魔術當長度屬性被縮短,但jQuery對象不會:

var arr = [1,2,3], $arr = $('div'); // assuming three divs 
arr.length=2; arr[2]; // undefined 
$arr.length=2; $arr[2]; // still references the div 

http://jsfiddle.net/cnkB9/

所以jquery的makeArray轉換jquery的陣列狀物體,並且使它成爲一個真正的本地js數組,但正如你所說,然後它沒有附加所有的jquery方法。

至於爲什麼在控制檯中顯示出來,我指的是這個優秀的答案:What makes Firebug/Chrome console treat a custom object as an array?解釋了length財產的存在和splice功能,允許它在控制檯看起來像一個數組。如前所述,FF4的Web控制檯並不是這種情況,它只是告訴你它不是本地的js數組。有趣的是,splice函數實際上並不需要工作,只是存在,並且是一個函數。例如:

>> console.log({length:2,0:'some',1:'thing',splice:new Function}); 
["some", "thing"] 
5

如何變換由jQuery選擇在操作與天然JavaScript數組返回陣列下面的簡單代碼:

var $arr = $('option'); // assuming three options 
var arr = Array.apply(null, $arr); 
// arr contains [option, option] 

考慮到以上代碼的以下HTML:

<html> 
    <head> 
     <script type="text/javascript" src="jquery-1.5.2.min.js"></script> 
    </head> 
    <body> 
     <select id="addSelection"> 
      <option value="Original Value">Original Value</option> 
      <option value="Two Value">Value two</option> 
      <option value="Three Value">Value three</option> 
     </select> 

     <br /> 

     <input id="btn" type="button" value="Changes" /> 
    </body> 
</hmtl>