关于javascript:TypeError:变量未定义

TypeError: variable is undefined

本问题已经有最佳答案,请猛点这里访问。

我收到以下错误:TypeError:slides [i]未定义。

它奇怪,因为它不应该能够访问幻灯片变量?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    $('document').ready(function() {
        $.ajax({
            type:"POST",
            url:"getSlides.php",
            data: '',
            cache: false,
            success: function(response)
            {
                var slides = JSON.parse(response);
                for (var i = 0; i < slides.length; i++) {
                    setTimeout(function() {
                        if (slides[i].type === 'image') {
                            $('#slideshow').html('<img src="' + slides[i].image_video + '" />');
                        }
                    }, 2000);
                }
            }
        });
    });


您可以代理您的sildes[i]setTimeout函数回调,参考,小提琴示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$('document').ready(function () {
    $.ajax({
        type:"POST",
        url:"getSlides.php",
        data: '',
        cache: false,
        success: function (response) {
            var slides = JSON.parse(response);
            for (var i = 0; i < slides.length; i++) {
                setTimeout(function (slide) {
                    if (slide.type === 'image') {
                        $('#slideshow').html('<img src="' + slide.image_video + '" />');
                    }
                }, 2000, slides[i]);
            }
        }
    });
});

它看起来像循环问题中的经典闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$('document').ready(function () {
    $.ajax({
        type:"POST",
        url:"getSlides.php",
        dataType: 'json',
        cache: false,
        success: function (response) {
            $.each(slides, function (slide) {
                if (slide.type === 'image') {
                    $('#slideshow').html('<img src="' + slide.image_video + '" />');
                }
            })
        }
    });
});


尝试替换:

1
for (var i = 0; i < slides.length; i++) {

至:

1
for (var i  in slides) {


因为setTimeOut它会在2000ms之后调用你的代码,在那个时候i的值是slide.length,它会抛出错误。

您必须安排为每个超时功能提供"i"的不同副本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 success: function (response) {
     var slides = JSON.parse(response);
     for (var i = 0; i < slides.length; i++) {
         doSetTimeout(slides, i);

     }
 }

 function doSetTimeout(slides, i) {
     setTimeout(function () {
         if (slides[i].type === 'image') {
             $('#slideshow').html('<img src="' + slides[i].image_video + '" />');
         }
     }, 2000);
 }

如果我没有误会,这是一个经典错误,setTimeout将在循环结束后执行async,所以在回调运行时我应该等于slides.length。 要解决此问题,请为i创建一个本地范围,如下所示:

1
2
3
4
5
6
7
8
9
                for (var i = 0; i < slides.length; i++) {
                    (function(i){
                      setTimeout(function(callback) {
                        if (slides[i].type === 'image') {
                            $('#slideshow').html('<img src="' + slides[i].image_video + '" />');
                        }
                      }, 2000);
                    })(i)
                }