Javascript 递归函数未定义错误

Javascript 递归函数未定义错误,javascript,function,recursion,defined,Javascript,Function,Recursion,Defined,嗨,我有一个递归问题 我遵循了wc3中的这个示例 但我的似乎根本不起作用 function rotateImages(start) { var a = new Array("image1.jpg","image2.jpg","image3.jpg", "image4.jpg"); var c = new Array("url1", "url2", "url3", "url4"); var b = document.getElementById('rotating1'); va

嗨,我有一个递归问题

我遵循了wc3中的这个示例 但我的似乎根本不起作用

function rotateImages(start)
  {
  var a = new Array("image1.jpg","image2.jpg","image3.jpg", "image4.jpg");
  var c = new Array("url1", "url2", "url3", "url4");
  var b = document.getElementById('rotating1');
  var d = document.getElementById('imageurl');
  if(start>=a.length)
      start=0;
  b.src = a[start];
  d.href = c[start];
  window.setTimeout("rotateImages(" + (start+1) + ")",3000);
  }

  rotateImages(0);
Firebug抛出错误:

rotateImages is not defined
[Break On This Error] window.setTimeout('rotateImages('+(start+1)+')',3000);
但是,如果我将超时更改为:

window.setTimeout(rotateImages(start+1),3000);
它是递归的,但不知怎么的,延迟不起作用,给了我太多的递归(每秒7000次)

试试下面的语法:

window.setTimeout(function() {
    rotateImages(start+1);
},3000);
setTimeout()
要求函数引用作为第一个参数。简单地将函数调用放在那里会给出te函数的返回值作为参数,这就是延迟不起作用的原因。但是,您第一次尝试评估字符串是一种很好的方法,但不推荐使用。

尝试以下语法:

window.setTimeout(function() {
    rotateImages(start+1);
},3000);

setTimeout()
要求函数引用作为第一个参数。简单地将函数调用放在那里会给出te函数的返回值作为参数,这就是延迟不起作用的原因。但是,您第一次尝试评估字符串是一种很好的方法,但不推荐使用。

应该避免使用
eval
的原因有很多,它破坏了作用域是其中之一。将字符串传递给setTimeout会在计时器用完时使其
eval
ed

您应该传递一个函数

window.setTimeout(rotateImages(start+1),3000);
这会立即调用
rotateImages
,然后将其返回值传递给
setTimeout
。这没有帮助,因为
rotateImages
不返回函数

您可能想要:

window.setTimeout(rotateImages,3000,[start+1]);
或者创建一个匿名函数,将闭包包装在start和pass周围,而不是:

window.setTimeout(function () { rotateImages(start + 1); },3000);

后一个选项在浏览器中有更好的支持。

应该避免使用
eval
的原因有很多,它破坏了作用域是其中之一。将字符串传递给setTimeout会在计时器用完时使其
eval
ed

您应该传递一个函数

window.setTimeout(rotateImages(start+1),3000);
这会立即调用
rotateImages
,然后将其返回值传递给
setTimeout
。这没有帮助,因为
rotateImages
不返回函数

您可能想要:

window.setTimeout(rotateImages,3000,[start+1]);
或者创建一个匿名函数,将闭包包装在start和pass周围,而不是:

window.setTimeout(function () { rotateImages(start + 1); },3000);

后一个选项在浏览器中有更好的支持。

请小心来自W3的代码

其他答案给出了一个解决方案。我要补充的是,每次调用
rotateImages
函数时,您都在重新创建数组并重复DOM选择。这是不必要的

您可以按如下方式更改代码:

(function() {
    var a = ["image1.jpg","image2.jpg","image3.jpg", "image4.jpg"];
    var c = ["url1", "url2", "url3", "url4"];
    var b = document.getElementById('rotating1');
    var d = document.getElementById('imageurl');

    function rotateImages(start) {
      b.src = a[start];
      d.href = c[start];
      window.setTimeout(function() {
          rotateImages( ++start % a.length );
      }, 3000);
    }

    rotateImages(0);
})();

要警惕来自W3学校的代码

其他答案给出了一个解决方案。我要补充的是,每次调用
rotateImages
函数时,您都在重新创建数组并重复DOM选择。这是不必要的

您可以按如下方式更改代码:

(function() {
    var a = ["image1.jpg","image2.jpg","image3.jpg", "image4.jpg"];
    var c = ["url1", "url2", "url3", "url4"];
    var b = document.getElementById('rotating1');
    var d = document.getElementById('imageurl');

    function rotateImages(start) {
      b.src = a[start];
      d.href = c[start];
      window.setTimeout(function() {
          rotateImages( ++start % a.length );
      }, 3000);
    }

    rotateImages(0);
})();

第二种方法不适用于internet explorer,因此首选最后一种方法(或使用已定义的函数)。也有一个很好的处理方法(使用一个返回函数的函数)关于eval,你需要知道的是你不应该使用它。它把范围搞砸了。它很慢。很难调试。它有可能带来安全问题。使用我答案中的最后一个示例。第二个方法不适用于internet explorer,因此首选最后一个方法(或使用已定义的函数)。也有一个很好的处理方法(使用一个返回函数的函数)关于eval,你需要知道的是你不应该使用它。它把范围搞砸了。它很慢。很难调试。它有可能带来安全问题。使用我答案中的最后一个例子。W3C不是W3C。他们是一个低质量、广告覆盖的第三方教程网站,具有良好的SEO。你推荐什么好网站?W3C学校不是W3C。他们是一个低质量的,广告覆盖的,第三方教程网站,搜索引擎优化很好。你有什么好的网站推荐吗?谢谢你的回答和帮助重构我的代码!我喜欢这条线++开始%a。length@Yz洛:不客气。是的,使用模运算符是重置为0的好方法。感谢您的回答并帮助重构我的代码!我喜欢这条线++开始%a。length@Yz洛:不客气。是的,使用模运算符是重置为0的好方法。现在我明白了。。我怎么知道什么时候应该调用函数?如果需要函数的返回值。如果你想给出你的函数(稍后调用),你应该使用函数引用(不带大括号)或匿名函数。现在我明白了。。我怎么知道什么时候应该调用函数?如果需要函数的返回值。如果你想给出你的函数(稍后调用),你应该使用函数引用(不带大括号)或匿名函数。