查询JavaScript的关闭行为

时间:2019-06-18 09:34:19

标签: javascript function closures

我一直在跟踪一个示例代码,以演示JavaScript闭包的行为,但是解释不充分(或者至少我不理解该解释)。我希望有人向我解释以下代码为什么会如此表现,我已经花了好几个小时了。

本教程提供了一个行为异常的初始示例,该示例通过使用闭包来解决。

HTML文件:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Closures</title>
</head>
<body>

  <h1 class="closures"></h1>

  <ol>
    <li class="track">track 1</li>
    <li class="track">track 2</li>
    <li class="track">track 3</li>
    <li class="track">track 4</li>
    <li class="track">track 5</li>
    <li class="track">track 6</li>
    <li class="track">track 7</li>
    <li class="track">track 8</li>
    <li class="track">track 9</li>
    <li class="track">track 10</li>
  </ol>

  <script src="closure.js"></script>  
</body>
</html>

使用以下JavaScript:

var elNumber = document.getElementById('number');

function setupClickHandlers(){
  var tracks = document.getElementsByClassName('track');

  function clickHandler(){
      console.log(i); 
  }

  for (var i = 1; tracks.length + 1; i++){
    tracks[i].addEventListener("click",clickHandler);
  }
}

setupClickHandlers();

预期的行为应该是当您单击每个轨道li元素时,控制台应记录该轨道的编号。很简单!

它最初通过var循环遍历每个轨道,将clickHandler()作为回调传递,这只是将值i记录到控制台。

但是,结果不正确,因为var循环运行得太快,导致每个轨道将10记录到控制台。我了解这是因为在var循环完成且i达到10的值之后,clickHandler会触发

为解决此问题,对新功能setupClickHandlers()进行了如下修改:

function setupClickHandlers(){
  var tracks = document.getElementsByClassName('track');

  function generateClickHandler(i){
    return function clickHandler(i){
      return console.log(i);
    }
  }

  for (var i = 0; tracks.length; i++){
    tracks[i].addEventListener("click",generateClickHandler(i));
  }
}

i现在作为参数传递到generateClickHandler(i)中,在那里函数返回到事件侦听器,从而解决了问题。

我只是不知道为什么这样做,返回回调函数是否意味着循环等待?为什么初始示例的行为方式不同?希望有人可以帮忙...

0 个答案:

没有答案