一般来说,当循环访问数组时,您希望使用它的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