在再次调用函数时,不会重新初始化变量

时间:2016-07-19 13:30:27

标签: javascript jquery

我从堆栈ar中的一个项目开始。

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

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

HTML:

<a href="javascript:void(0);" id="l1">Link 1</a>
<a href="javascript:void(0);" id="l2">Link 2</a>
<a href="javascript:void(0);" id="l3">Link 3</a>
<a href="javascript:void(0);" id="l4">Link 4</a>
<div id="log"></div>

的Javascript

function check() {
  var index = 0;
  $('body').click(function(event) {
    var log = $('#log');
    alert(index);

    if ($(event.target).is(ar[index])) {
      log.html(index + ' ' + event.target.id + ' was clicked.');
      index++;

      if (index === ar.length) {
        //if all clicked elements corresponded to correct 
        //order in array and reached end of array
        level +=1;
        console.log("Passing to next level. ", level);
        randomId();
        console.log(ar);
        log.html(ar);
        check();
      }
    } 
    else {
      log.html(index + ' ' + event.target.id + ' was clicked. Is wrong');  
      index = 0;
    }
  });
}

var ar = [];  
divIds = ["#l1", "#l2", "#l3", "#l4"];
level = 1;
randomId();
check();

function randomId() {
  var min = 0;
  var max = 3;
  var id = Math.floor(Math.random() * (max-min+1)) + min;
  var selectedId = divIds[id];

  ar.push(selectedId);
  alert(ar);
}

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

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

2 个答案:

答案 0 :(得分:0)

已更新 - 删除了index参数,因为它不需要

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

  • index level添加为check函数的参数
  • 在调用index(自我调用)时将起始值传递给 level / check()
  • 替换使用check() 删除内部index = 0;

这样,check函数参数 index level将像非全局静态变量一样工作,这很可能是你需要的

我还建议您为变量等应用对象,而不是使用全局变量。

旁注:我无法获得实际代码的工作方式。在放弃使用index并进行一些调整之后,它开始了。这是你打算如何工作,或者'index'变量的目的是什么

var MyApp = {};
MyApp.ar = [];
MyApp.divIds = ["#l1", "#l2", "#l3", "#l4"];

(function check(level) {
  randomId();
  $('body').click(function(event) {
    var log = $('#log');
    if ($(event.target).is(MyApp.ar[level-1])) {
      log.html(event.target.id + ' was clicked.');
      if (level === MyApp.ar.length) {
        //if all clicked elements corresponded to correct 
        //order in array and reached end of array
        level++;
        console.log("Passing to next level. ", level);
        randomId();
        console.log(MyApp.ar);
      }
    } else {
      log.html(event.target.id + ' was clicked. Is wrong');
    }
  });
})(1);

function randomId() {
  MyApp.ar.push(MyApp.divIds[Math.floor(Math.random() * MyApp.divIds.length)]);  
  alert(MyApp.ar);
}
a {
  padding: 0 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="javascript:void(0);" id="l1">Link 1</a>
<a href="javascript:void(0);" id="l2">Link 2</a>
<a href="javascript:void(0);" id="l3">Link 3</a>
<a href="javascript:void(0);" id="l4">Link 4</a>
<div id="log"></div>

答案 1 :(得分:-1)

您在此处遇到的内容称为“闭包”。基本上,您将在另一个函数范围内定义的函数绑定到click事件。所有点击都会引用其范围的相同outer index并进行修改。

了解更多here

如果在阅读之后你仍然无法理解这里的问题,请在这里发表评论,我会尽力帮助,我只是不想重复其他人所说的话。

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

$('body').click(function(event){})

这行代码是您的点击工作的原因。您不需要多次运行check(),因为一旦您拥有&#34;附加&#34;事件处理程序一次,你只需要检查值不反复重新绑定它。

换句话说,让check()仅运行一次,并将index放在绑定的click函数中而不是外部,如果您希望每次单击它时重置它。如果您希望仅在经过一定量的点击后重置它,您需要将其保持在函数关闭之外,如下所示:

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

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