试图理解一个闭包函数

Iss*_*lan 3 javascript closures function

我在谷歌的帮助下做了一个关闭功能.该功能可以正常工作.但是,我不确定它是如何工作的.

function ShowQuestion(i) {
  console.log(i); // here 1 to 10 are logged immediately.
  return function() {
    console.log(i); // here the number are only logged when I mouse over on any li.
  }
}

setTimeout(function() {    
  for (i = 0; i < document.getElementById('Previousli').getElementsByTagName('ul')[0].children.length; i++) {
    document.getElementById('Previousli').getElementsByTagName('ul')[0].children[i].onmouseover = ShowQuestion(i);
  }    
}, 10000);
Run Code Online (Sandbox Code Playgroud)

首先,我想知道为什么第一个console.log(i)在10秒超时后立即记录1到10,但是第二个console.log(i)只有当我鼠标悬停在li上时才记录"index" ?

T.J*_*der 6

我想知道为什么第一个console.log(i)在10秒超时之后立即记录1到10

因为超时回调有一个循环并且ShowQuestion在循环中调用.第一个声明ShowQuestionconsole.log,所以你看到所有这些,一个接一个地,当循环运行.

但是第二个console.log(i)只有在鼠标悬停在li上时才会记录"索引"?

因为ShowQuestion返回一个函数; 循环代码将该函数分配给onmouseover元素的属性,使其成为事件的老式事件处理程序mouseover.ShowQuestion除非发生该事件,否则创建的函数不会运行,并且只要该事件发生,就会重新运行.

你可能想知道为什么/该事件处理程序是如何显示i的时候i是提供一个参数ShowQuestion,并通过处理程序被运行时间mouseover事件,ShowQuestion已经返回.答案是函数ShowQuestioncreate是对特定调用的上下文的闭包ShowQuestion,包括范围内的参数和变量.因此,即使与其相关的呼叫已经完成i,每个呼叫的每个副本都会ShowQuestion存活下来ShowQuestion.

更多: