setTimeout无法访问变量

时间:2018-12-29 08:17:17

标签: javascript jquery function variables settimeout

我正在上一门编程课程,其中一个项目是在Javascript上创建一个西蒙说游戏,我想添加的功能之一是,每次关卡开始时,游戏都会经历为了使用户更好地调用该序列,我创建了下一级函数:

function nextLevel(){
    //increasing level by one
    level++;

//Changing title to show level
$('h1').text('Level '+level);

    //Repeating the sequence (with the user sequence first as a test)

    var i;
    for(i=0; i <= userMemory.length; i++){
        var currentColor = userMemory[i];

        //Sequence walkthrough
            setTimeout(function(){
                makeSound(currentColor);
                $("#"+currentColor).addClass("pressed");
                $("#"+currentColor).fadeOut(200).fadeIn(200);
                $("#"+currentColor).removeClass("pressed");
            }, 1000, currentColor);

    }
};

事情是,当我想重复序列时,我想使其按顺序进行,并且有点慢,因为如果我只是这样做的话:

for(i=0; i <= userMemory.length; i++){
            var currentColor = userMemory[i];
                    makeSound(currentColor);
                    $("#"+currentColor).addClass("pressed");
                    $("#"+currentColor).fadeOut(200).fadeIn(200);
                    $("#"+currentColor).removeClass("pressed");
}

它会一次播放数组中的所有按钮,这就是为什么我想使用setTimeout函数的原因,但是令我惊讶的是,当它尝试播放时,它既不会播放也不将效果应用到按钮,并且控制台会记录我的错误消息好像setTimeout函数无法分辨currentColor变量是什么,似乎它超出了范围(即使变量位于同一函数内)我在做错什么吗?如何将变量传递给setTimeout?

预先感谢:)

1 个答案:

答案 0 :(得分:1)

异步做到了...在调用回调时,对于所有实例,currentColor将是未定义的,因为它分配给userMemory 1的值大于该数组中的项目数(即,您有两个问题)加上代码)

解释数组问题...假设您有一个数组

let array = ['a', 'b', 'c']

项目的索引是0、1和2

for (i=0; i <= array.length; i++) {
    console.log(array[i]);
}

将输出a,b,c和undefined-当i == 3时

希望如此。

此外,根据评论,您似乎还希望每次迭代都在上一次迭代之后1秒

您需要将每个setTimeout设置为比上一个设置长1秒

现代浏览器修复-使用let

// note, use < not <= ... an array of length 1 has 1 item, at index 0
for(let i=0; i < userMemory.length; i++){
    let currentColor = userMemory[i];

    //Sequence walkthrough
        setTimeout(function(){
            makeSound(currentColor);
            $("#"+currentColor).addClass("pressed");
            $("#"+currentColor).fadeOut(200).fadeIn(200);
            $("#"+currentColor).removeClass("pressed");
        }, (i + 1) * 1000, currentColor);

}

其他可能的解决方法-使用功能

function doThings(delay, currentColor) {
        setTimeout(function(){
            makeSound(currentColor);
            $("#"+currentColor).addClass("pressed");
            $("#"+currentColor).fadeOut(200).fadeIn(200);
            $("#"+currentColor).removeClass("pressed");
        }, delay, currentColor);
}
for(i=0; i < userMemory.length; i++){
    doThings((i+1) * 1000, userMemory[i]);
}