我从开始学习Javascript(有趣!),书中的一个特定例子似乎有些过头了。我知道他们有时会做一些不是严格意义上的最佳实践的事情,比如使用document.write,让例子变得非常容易理解。但这似乎是相反的情况:他们使用的似乎是一种非常复杂的方式来做某事,这让我怀疑是否有我不理解的原因。
请参阅下面的示例。该示例的目的是创建两个图像,每次单击它们时都会更改图像源。我的问题与他们使用indexOf搜索单个字符串(而不是数组)有关——这看起来很奇怪。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Chapter 10: Example 1</title>
</head>
<body>
<img src="usa.gif" onclick="changeImg(this)" />
<img src="mexico.gif" onclick="changeImg(this)" />
<script>
var myImages = [
"usa.gif",
"canada.gif",
"jamaica.gif",
"mexico.gif"
];
function changeImg(that) {
var newImgNumber = Math.round(Math.random() * 3);
while (that.src.indexOf(myImages[newImgNumber]) != -1) {
newImgNumber = Math.round(Math.random() * 3);
}
that.src = myImages[newImgNumber];
}
</script>
</body>
</html>
因此,与其使用indexOf,不如编写以下内容:
while (that.src == myImages[newImgNumber])) {
newImgNumber = Math.round(Math.random() * 3);
}
这样行吗?当人们查看代码时,似乎更容易理解。或者有充分的理由按照他们的方式去做吗?
更新:经过几分钟的思考,我想我知道答案了。我猜src将作为一个长字符串返回,而不是myImages数组中包含的短字符串。所以他们需要使用indexOf来发现myImages中的字符串是否在that.src中的src中。对吗?
顺便说一句,他们创建随机数的方法让我很恼火——而不是:
newImgNumber = Math.round(Math.random() * 3);
我更喜欢:
newImgNumber = Math.floor(Math.random() * 4);
第一种方法不会在数组的四个元素之间创建均匀分布。但也许他们只是觉得圆形和地板的区别不值得在初学者的书中深入探讨。
问题是src
IDL属性将返回将相对URL解析为绝对URL的结果。
相反,您可以使用getAttribute
来获取src
内容属性:
var img = document.images[0];
document.body.innerHTML = ''
+'<dl>'
+'<dt>src IDL attribute:</dt>'
+'<dd>' + img.src + '</dd>'
+'<dt>src content attribute:</dt>'
+'<dd>' + img.getAttribute('src') + '</dd>'
+'</dl>';
<img src="usa.gif" />
因此,我会使用这样的东西:
var myImages = [
"usa.gif",
"canada.gif",
"jamaica.gif",
"mexico.gif"
];
var els = document.getElementsByClassName('myclass');
for(var i=0; i<els.length; ++i)
els[i].addEventListener('click', changeImg);
function changeImg() {
var newImgNumber;
do {
newImgNumber = Math.floor(Math.random() * myImages.length);
} while (this.getAttribute('src') == myImages[newImgNumber]);
this.src = myImages[newImgNumber];
}
<img src="usa.gif" class="myclass" />
<img src="mexico.gif" class="myclass" />
有一个很棒的JavaScript库,叫做下划线。http://underscorejs.org/
除了许多其他非常有用的函数外,这个库还有一个简单的包含函数,可以用来发现数组的内容。既然你正在学习,我想向你介绍一下这个图书馆可能会很有用。
使用indexOf来发现弹簧的内容并不是过分的,您可能为发现集合的元素而执行的任何类型的实现都将与indexOf完全一样,在集合上迭代,直到找到目标元素。但我个人觉得indexOf的语法非常麻烦(!=-1讨厌它),所以我尽量少用它。