矫枉过正?使用 indexOf() 发现字符串的内容

Overkill? Using indexOf() to discover contents of a string

我正在从头开始学习 Javascript(有趣!)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);

第一种方法不会在数组的四个元素之间创建均匀分布。但也许他们只是认为圆形与地面的区别不值得在初学者的书中讨论。

有一个很棒的 JavaScript 库叫做 underscore。 http://underscorejs.org/

除了许多其他非常有用的函数之外,该库还有一个简单的包含函数,可用于发现数组的内容。由于您正在学习,我认为向您介绍此库可能会有用。

使用 indexOf 来发现 spring 的内容并不过分,您可能为发现集合元素而执行的任何类型的实现都将完全执行 indexOf 所做的事情,遍历集合直到您的目标找到元素。但我个人觉得 indexOf 的语法非常繁琐(!= -1 讨厌它)所以我尽量少用它。

问题是 src IDL attribute will return the result of resolving your relative URL to an absolute one.

相反,您可以使用 getAttribute to get the src content attribute:

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" />