Javascript 再次调用函数时,变量未重新初始化

Javascript 再次调用函数时,变量未重新初始化,javascript,jquery,Javascript,Jquery,我从堆栈中的一项开始ar 我打算让代码做的是:如果用户单击正确的链接(一台计算机随机选择的链接),我们将进入下一个“级别”,在那里我们将向堆栈中添加一个元素 在下一个级别中,用户必须按照它们在堆栈中的顺序选择2个正确的链接。一旦用户这样做,他就应该进入下一个级别,以此类推。这类似于西蒙·赛义德的游戏,我只是想用这个来模仿游戏的基本逻辑 HTML: 但是,当我第二次调用check()函数时(当我们移动到堆栈中有2个元素的第2级时),index的值不是0,尽管var index=0是check()函

我从堆栈中的一项开始
ar

我打算让代码做的是:如果用户单击正确的链接(一台计算机随机选择的链接),我们将进入下一个“级别”,在那里我们将向堆栈中添加一个元素

在下一个级别中,用户必须按照它们在堆栈中的顺序选择2个正确的链接。一旦用户这样做,他就应该进入下一个级别,以此类推。这类似于西蒙·赛义德的游戏,我只是想用这个来模仿游戏的基本逻辑

HTML:

但是,当我第二次调用
check()
函数时(当我们移动到堆栈中有2个元素的第2级时),index的值不是0,尽管
var index=0
是check()函数的第一行


我正在使用console.log和alert来捕获索引的值,但它们的绝对数量让我感到困惑。通过查看警报弹出窗口的数量,我的检查功能看起来就像一个循环。当我们第二次调用函数时,为什么我们没有得到一个干净的记录呢?

您在这里遇到的是所谓的闭包。基本上,您是将在另一个函数范围内定义的函数绑定到单击事件。所有单击都引用其作用域的相同
外部索引
,并对其进行修改

阅读更多

如果在阅读之后,你仍然无法理解这里的问题是什么,请在这里发表评论,我将尽我所能提供帮助,我只是不想重复别人说过的话

编辑:正如其他人指出的那样,这里还有另一个问题,即,您要多次绑定单击事件。您必须删除以前的绑定(甚至更好),只需更改值,不要绑定多个事件

$('body').click(function(event){})
这行代码使您的单击工作。您不需要多次运行
check()
,因为一旦“附加”了事件处理程序一次,您只需要检查值,而不需要反复绑定它

换句话说,让您的
check()
只运行一次,如果您想在每次单击时重置
函数,请将
索引
放在绑定的
单击
函数内而不是外部。如果只想在单击一定次数后重置,则需要将其保持在函数关闭之外,如下所示:

function check(){
  index = 0;
  $('body').click(function(event){
    //NO INDEX HERE
  })
}

但是在这种情况下(这就是您现在拥有的),您需要在某些条件下,从您绑定到单击的函数中手动重置它。例如
if(ar>neededNumber){index=0;}

更新-删除了
索引
参数,因为它不是必需的

如果我正确理解您的代码示例,您可以这样做

  • 索引
    级别
    作为参数添加到
    检查
    功能中
  • 调用
    检查()
    (自调用)时,将开始值传递给
    索引
    /
    级别
  • index=0替换并移除内部
    check()
这样,
check
functions参数、
index
level
将像一个非全局静态变量一样工作,这很可能是您所需要的

我还建议为您的变量等创建一个应用程序对象,而不是使用全局变量

旁注:我无法让实际代码按照它看起来应该如何工作的方式工作。在放弃了
索引的使用和一些调整之后,它开始恢复。这就是您希望它工作的方式,或者'index'变量的用途是什么

var MyApp={};
MyApp.ar=[];
MyApp.divIds=[“l1”、“l2”、“l3”、“l4];
(功能检查(水平){
randomId();
$('body')。单击(函数(事件){
var log=$('#log');
if($(event.target).is(MyApp.ar[level-1])){
html(已单击event.target.id+);
if(level==MyApp.ar.length){
//如果所有单击的元素对应于正确的
//在数组中排序并到达数组末尾
级别++;
console.log(“传递到下一个级别。”,级别);
randomId();
console.log(MyApp.ar);
}
}否则{
html(event.target.id+“已单击。错误”);
}
});
})(1);
函数randomId(){
MyApp.ar.push(MyApp.divIds[Math.floor(Math.random()*MyApp.divIds.length)];
警报(MyApp.ar);
}
a{
填充:0 10px;
}


每次调用
check()
时,您都在向
添加额外的事件处理程序。上一个
check()
调用中的处理程序不会神奇地消失。即,在调用两次
check()
后,单击
将执行两个事件处理程序。如果这是问题所在,请在绑定新的事件处理程序之前删除现有的事件处理程序。为什么要一次又一次地附加click处理程序?这实际上比这更糟糕,因为每次调用
check()
,都会创建新的click处理程序,并且每个处理程序都有自己封闭的
索引只有一次,然后才是正在运行的单击。但是,如果他每次重置值时都要执行check(),那么他最终会绑定多个函数,这确实会使情况变得更糟,但从代码判断,他只调用一次check()。这是一个公平的观点。不,他一遍又一遍地检查。。。仔细看一看,你会发现上帝,我甚至没有注意到再次运行它的部分代码,不管怎样,这是两个独立的问题,都需要解决。(我知道你已经看到了,但除了阅读代码之外,问题明确指出它再次被调用:“但是当我第二次调用check()函数[…])是的,谢谢,这正是我想要的代码。我再次调用check(),认为它是在重新启动函数,重置变量和所有内容。但正如你们所有人
$('body').click(function(event){})
function check(){
  index = 0;
  $('body').click(function(event){
    //NO INDEX HERE
  })
}