一般來說,當循環訪問數組時,您希望使用它的length
屬性作爲本書的解決方案。你的解決方案在這種情況下也應該很好,但它有一個弱點:對於數組中的一個入口是0
,null
,0 undefined
或false
,它們都是「假」值並且所以即使你不在數組的末尾,document.links[i]
也可能是假的。
例子:
var index, a;
a = [3, 2, 1, 0, -1, -2];
for (index = 0; a[index]; ++index) {
alert(a[index]);
}
這將提醒3
,2
和1
,但是隨即停止。對比:
var index, a;
a = [3, 2, 1, 0, -1, -2];
for (index = 0; index < a.length; ++index) {
alert(a[index]);
}
...這將提醒3
,2
,1
,0
,-1
和-2
。
您可能會看到如下所示的代碼:for (index in a)
。一般來說,不要用它來循環數組索引,它是基於對什麼for..in
做什麼的誤解。 (更多關於下面的內容)
(在新的第5版規範中增加了另外一種循環數組條目的新方法:forEach
函數。給它一個函數,併爲每個函數調用它數組中的元素。Details in this other answer.。可悲的是,IE8不支持它,但它的事情之一,可以「勻」 —搜索「ES5墊片」的多個選項。)
當得知陣列,知道Javascript數組與其他大多數語言中的數組非常相似,這一點很重要。首先,他們不是(一定)陣列;實際上,它們只是普通的Javascript對象,並增加了一些特殊功能。 Javascript對象是屬性映射,它們將鍵映射到值。例如:
var obj = {foo: 1};
這obj
對象映射的關鍵"foo"
(字符串)值1
。您可以通過在代碼中使用文字名稱或使用[]
和字符串來訪問該屬性。當然,如果你在做後者,你可以使用任何字符串(文字或從變量或從表達式等)。因此,所有這些都有相同的結果:
x = obj.foo;
x = obj["foo"];
name = "foo";
x = obj[name];
name = "o";
x = obj["f" + name + name];
...你明白了;只要你在[]
中使用的是一個字符串,你可以使用該鍵查找值。但使用Javascript也確實隱含的強制,所以此工程:
var obj = {"1": "one"};
alert(obj[1]); // alerts "one"
在那裏,我已經制定了一個名爲"1"
到值"one"
屬性。但後來我用obj[1]
來查找它,使用數字而不是字符串。沒關係,解釋器會把它變成一個字符串,然後做關鍵字查找。
這與數組有什麼關係?這:數組索引只是屬性名稱。 JavaScript數組是一個正常的對象,鍵映射到值,具有這些特殊功能:
每當你的名字可以被解釋爲數字的屬性,如果這個數字比目前的最高指數出現較大的在數組中,length
屬性已更改。所以:
var a = ["zero"];
alert(a.length); // alerts 1
a[3] = "three";
alert(a.length); // alerts 4, because the max index is now 3
每當你length
,如果有與具有大於或等於新的長度值數字名稱的屬性,這些屬性是從對象中刪除。
var a = ["zero", "one", "two", "three"];
alert(a[3]); // alerts "three"
a.length = 3;
alert(a[3]); // alerts "undefined", the "3" property has been deleted
// only the "0", "1", and "2" properties remain
他們有他們從Array.prototype,像join
或splice
繼承功能的各種屬性。
就是這樣。完全不像C,C++,Java或其他大多數語言中的數組。
由於磁盤陣列的只是一對夫婦的額外功能的對象,你可以把陣列等,非數字屬性,如果你想:
var a = ["zero", "one", "two"];
a.foo = "bar";
alert(a[1]); // alerts "one", 1 is implicitly coerced to "1"
alert(a["1"]); // alerts "one"
alert(a.foo); // alerts "bar"
alert(a["foo"]); // alerts "bar"
而這正是該for..in
事情打破了:因爲for..in
不通過數組索引不循環,它遍歷屬性名稱:
var a, name;
a = [1, 2, 3];
a.foo = "bar";
for (name in a) {
alert(name);
}
這提醒"1"
,"2"
,"3"
和"foo"
(沒有特別的順序)。你可以看到,如果你認爲它只是數組索引,你會遇到麻煩!您可以用它來循環數組索引,但它更復雜,比它的價值:
for (name in a) {
if (String(Number(name)) === name && a.hasOwnProperty(name)) {
alert(name);
}
}
,首先檢查是否屬性名稱是一個數字,然後檢查該財產的定義上a
本身,而不是Array.prototype(請記住,數組繼承了Array原型的屬性)。 (公平地說,後面的檢查可能不是那麼重要;如果有人向Array原型添加數字命名的屬性,他們會做一件非常糟糕的事情。)
是的,那是真的。 – 2010-05-23 08:01:43