2011-02-28 39 views
46

我只是瀏覽灒的源代碼,我碰到這行代碼來:Array.prototype.slice.call(array,0)有什麼用?

array = Array.prototype.slice.call(array, 0); 

我擡起頭的功能是什麼,但我得出的結論,它只是返回數組從開始的所有元素索引0,並將整體放入數組中,即它根本沒有做任何事情。

因此,這行代碼的用途是什麼?我錯過了什麼?

編輯:它是從https://github.com/jquery/sizzle/blob/master/sizzle.js#L863線863。

+1

似乎有點糾結的調用'array.slice(0)'的方式,它會複製數組。但我不明白爲什麼它會以這樣一種難以穿透的方式被調用。 – spender

+8

上下文使所有不同。數組標識符沒有引用實際的數組。 – user113716

回答

75

對於像getElementsByTagName這樣的大多數操作,DOM通常會返回NodeList

雖然NodeList幾乎感覺像一個數組,但事實並非如此。它具有像數組一樣的length屬性,以及訪問給定索引處的對象的方法item(index)(也可以用[index]表示法訪問),但這就是相似性結束的地方。

因此,爲了能夠使用美妙的array methods而不用全部重寫它們的NodeList,以上行是有用的。

將它轉換爲數組的另一種用法是使列表成爲靜態。 NodeLists通常是活的,這意味着如果發生文檔更改,NodeList對象會自動更新。這可能會導致問題,如果一個jQuery對象返回給你不斷變化在你的鼻子下。嘗試以下snippet來測試NodeLists的活躍度。

var p = document.getElementsByTagName('p'); 
console.log(p.length); // 2 
document.body.appendChild(document.createElement('p')); 
// length of p changes as document was modified 
console.log(p.length); // 3 
+3

廢話這個答案拖得我更接近實際擁抱JS。無論如何,我一直希望它能夠永遠消失... +1。 – Lee

+0

我產生的一個問題是:你怎麼知道數組方法可以應用到什麼對象?顯然,它是具有length屬性的任何對象,以及整數屬性名稱(從零開始?)。我還了解到「參數」變量是一個類似於對象的數組,但不是一個實際的數組(我不知道)。答案在這裏:http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work – zod

+1

@zod:如果你看看[V8的實現](http://code.google .com/p/v8/source/browse/trunk/src/array.js#617)然後[看起來似乎](http://code.google.com/p/v8/source/browse/trunk/ src/array.js#321)是不可思議的事情。它使用'.length'來確定範圍,然後執行'for'循環來複制正確的元素(這隻需要一個帶有數字鍵的對象)。 – pimvdb

6

正如BoltClock所說,它使得數組的一個(淺)副本。它也可以用來複制差不多的數組,例如內建的arguments,它的原型鏈中有長度和項目但沒有數組(因此沒有切片方法)。

+0

我是這麼認爲的,但它將結果賦給同一個'array',所以我無法弄清楚真正發生了什麼。 – BoltClock

+0

請問爲什麼var不放在它之前?如果創建了一個副本,那麼它是不是一個新的變量,即使用'var'? – pimvdb

+0

@BoltClock,嗯......那很奇怪。也許這是爲了讓Array原型不是真的,比如參數或者jQuery集合。 – harpo

10

這裏發生的事情是,Sizzle正在創建一個陣列類對象的實際數組。類似數組的對象不一定具有slice()方法,所以原型方法必須直接調用。 makeArray()返回該數組類對象的一個​​副本,該對象是一個實際的數組,並且可以用作其他位置。請參閱here瞭解有關類似數組的對象的更多信息。

相關問題