setTimeout 无法访问变量
setTimeout can't access variable
我正在上一门编程课程,其中我的一个项目是在 Javascript 上创建一个 Simon says 游戏,我想添加的其中一个功能是每次关卡开始时游戏都会运行通过序列的每一种颜色,以便用户更好地回忆序列,为此我创建了这个下一级函数:
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?
提前致谢:)
异步会这样做...在调用回调时,对于所有实例,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]);
}
我正在上一门编程课程,其中我的一个项目是在 Javascript 上创建一个 Simon says 游戏,我想添加的其中一个功能是每次关卡开始时游戏都会运行通过序列的每一种颜色,以便用户更好地回忆序列,为此我创建了这个下一级函数:
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?
提前致谢:)
异步会这样做...在调用回调时,对于所有实例,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]);
}