问题是这样的:
创建包含许多链接的页面。然后编写触发窗口onload事件的代码,显示
页面上每个链接的href。
这是我的解决方案
<html>
<body language="Javascript" onload="displayLink()">
<a href="http://www.google.com/">First link</a>
<a href="http://www.yahoo.com/">Second link</a>
<a href="http://www.msn.com/">Third link</a>
<script type="text/javascript" language="Javascript">
function displayLink()
{
for(var i = 0;document.links[i];i++)
{
alert(document.links[i].href);
}
}
</script>
</body>
</html>
这是本书提供的答案
<html>
<head>
<script language=”JavaScript” type=”text/javascript”>
function displayLinks()
{
var linksCounter;
for (linksCounter = 0; linksCounter < document.links.length; linksCounter++)
{
alert(document.links[linksCounter].href);
}
}
</script>
</head>
<body onload=”displayLinks()”>
<A href=”link0.htm” >Link 0</A>
<A href=”link1.htm”>Link 2</A>
<A href=”link2.htm”>Link 2</A>
</body>
</html>
在进入有关如何检查用户浏览器版本或模型的JavaScript教程之前,我使用了与示例相同的方法,方法是为循环使用
length
数组的links
属性,但是在阅读完教程中,我发现我也可以使用这种替代方法,通过使用以下方法:仅当document.links[i]
返回有效值时,测试条件才评估为true,所以我的代码是否也使用有效方法编写?不是,关于如何编写更好的代码的任何评论?如果我写错了,请纠正我,我听说有些人说:“好的代码并不仅仅取决于它是否有效,而是在速度方面,理解代码的能力,并可能使其他人容易理解代码。”是真的吗?
最佳答案
通常,在遍历数组时,您要像本书的解决方案一样使用其length
属性。在这种特定情况下,您的解决方案也应该很好,但它有一个缺点:将数组中的条目为0
,null
,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 shim''以获得多个选项。)在学习数组时,重要的是要知道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原型添加了以数字命名的属性,那么他们的工作就非常糟糕了。)
关于javascript - 关于javascript BOM问题的一个小问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2891029/