2012-01-10 67 views
1

我有以下代碼:神祕「功能」被附接至陣列

// button sets 
    var sets = ['.diamond-colour','.diamond-cut','.diamond-clarity','.diamond-certificate']; 
    // for each set 
    for (set in sets){ 
     console.log('Set: '+set); 
     console.log(sets[set]); 
    } 

控制檯日誌顯示:

Set: 0 
.diamond-colour 
Set: 1 
.diamond-cut 
Set: 2 
.diamond-clarity 
Set: 3 
.diamond-certificate 
Set: findIndex 
function (value){ 
var ctr = ""; 
for (var i=0; i < this.length; i++) { 
if (this[i] == value) { 
return i; 
} 
} 
return ctr; 
} 

這似乎是與findIndex鍵作爲新的數組和一個值就是那個函數。

會有人知道這是什麼,爲什麼它出現?

回答

6

您應該使用傳統的for循環遍歷數組,否則您可能會拾取由您或第三方代碼添加的屬性(本例中爲新函數)。

for(var i = 0; i < sets.length; i++) { 

正如其他人所說,緩存長度提供最佳的性能:

for(var i = 0, len=sets.length; i < len; i++) { 
+2

'爲(VAR I = 0;我 Jasper 2012-01-10 23:28:54

+1

@Jasper有趣的測試。我不知道'for..in'會慢很多*。 – 2012-01-10 23:33:56

+0

@Jasper我的觀點是*不要用於......在數組*中,但這肯定是有用的信息。 – Dennis 2012-01-10 23:35:51

4

這是因爲in運營商與Javascript中循環遍歷對象的屬性,而不僅僅是在對象「陣列」。我說「數組」,因爲Javascript數組實際上只是具有爲數組中的每個條目創建的數字屬性的對象(以及一些其他方法和屬性,如.length)。

正如丹尼斯提到的,您將需要使用傳統的for循環來遍歷數組中的對象。

還要注意的是一個簡單的優化用於這種for循環是在循環的開始,一旦初始化長度值,而不是每次評估array.length

for (var i = 0, len = sets.length; i < len; i++) { 
    // ... 
} 
+1

用於緩存數組長度。這有助於它更快地執行,請參閱此性能測試以獲得證明:http://jsperf.com/jquery-each-vs-for-loops/2 – Jasper 2012-01-10 23:30:51

+0

ECMAScript第5版確實提供了一種機制,可以將屬性註釋爲不可枚舉,但是。 (但是通過索引迭代仍然是語義上正確的方法。) – 2012-01-10 23:35:12

+0

@pst很好知道,但ECMAScript 5th ed支持需要多長時間才能將其推廣爲有效的兼容解決方案?迭代這種方式應該在當前的第4版和未來的第5版中正確工作,對嗎? – GregL 2012-01-10 23:41:00