问题是:
创建包含多个链接的页面。然后编写在窗口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]
返回有效值时测试条件将评估为真的方法,我的代码也是如此是使用有效的方法编写的?如果不是,关于如何编写更好的代码的任何评论??如果我错了就纠正我,我听到一些人说“好的代码不仅仅评估是否有效或不是,但就速度而言,能够理解代码,并且可以让其他人轻易地理解代码“。这是真的吗?
答案 0 :(得分:5)
通常,在循环遍历数组时,您希望使用其length
属性作为本书的解决方案。你的解决方案在这个特定的情况下也应该没问题,但它有一个缺点:对于数组中的条目0
,null
,{完全有效{1}}或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)
所做的误解。 (更多内容见下文。)
(还有另一种循环数组条目的新方法已添加到新的第5版规范:for..in
函数。你给它一个函数,它为数组中的每个元素调用它。Details in this other answer.。可悲的是,IE8不支持它,但它是可以“填充”的东西之一 - 为多个选项搜索“es5 shim”。)
在了解数组时,重要的是要知道Javascript数组与大多数其他语言中的数组非常不同。首先,它们根本不是(必然)阵列;实际上,它们只是普通的Javascript对象,并添加了一些特殊功能。 Javascript对象是属性映射,它们将键映射到值。例如:
forEach
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"
查找,使用数字而不是字符串。没关系,解释器会把它变成一个字符串给我,然后进行密钥查找。
所有这些与数组有什么关系?这:数组索引只是属性名称。 Javascript数组是将键映射到值的普通对象,具有以下特殊功能:
每当您设置一个名称可以解释为数字的属性时,如果该数字大于数组中当前的最大索引,则会更改obj[1]
属性。所以:
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
它们具有从Array.prototype继承的函数的各种属性,如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
或join
。
就是这样。完全没有C,C ++,Java或大多数其他语言中的数组。
由于数组只是具有一些额外功能的对象,因此如果您愿意,可以在数组上放置其他非数字属性:
splice
这就是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);
}
}
本身上定义,而不是Array.prototype(请记住,数组从Array原型继承属性) 。 (公平地说,后一种检查可能并不是那么重要;如果有人在数组原型中添加了数字命名的属性,那么他们正在做一件非常糟糕的事情(tm)。)
答案 1 :(得分:0)
是的,代码确实不仅可以工作,而且易于理解。它被称为可管理性,是编写优秀代码的一个非常重要的方面。
让我们看看代码中的一些差异和一些问题以及提供的答案:
您缺少HTML文档中的head
部分。文档必须是有效的HTML。
提供的答案缺少title
中的head
标记,这也是必需的。
Javascript标记应该最好位于文档的head
部分。它可以在正文中使用脚本标记,但这是非标准的,因此如果没有特定的原因,应该避免使用它。
脚本代码的language
属性已被弃用多年,只需要type
属性。
您正在使用变量i
进行循环,这是一个众所周知的约定。为变量提供描述性名称是良好编码的另一个方面,但这并不意味着每个变量都必须具有长名称。一些易于识别的变量,如循环计数器,可以有短名称。
检查集合的长度比检查有效值更好,它更适合您实际想要做的事情。在这种情况下检查有效值是有效的,但是如果你有一个可以包含空值的集合,那么循环将停在第一个空值,从而缩短循环次数。
所以,通过添加一些有用的东西,比如doctype声明(以标准模式而不是quirks模式进行页面渲染)和页面内容的块标记,我建议代码看起来像这样: / p>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Links test</title>
<script type="text/javascript">
function displayLink() {
for(var i = 0; i < document.links.length; i++) {
alert(document.links[i].href);
}
}
</script>
</head>
<body onload="displayLink();">
<div>
<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>
</div>
</body>
</html>