所以我理解闭包和循环引用(我希望),但是一个方面是循环中报道的很多闭包,这似乎引起了很多麻烦。我需要澄清一下。我正在看的代码是:
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
function getHelp(help) {
alert(help);
// only to show value of "help" at this point, also to prove that "getHelp()" is being called even
// though the onfocus wasn't used
return function() {
showHelp(help);
}
}
function setupHelp(){
var helpText = [
{'id':"email",'help':"Your email address"},
{'id':"name",'help':"Your full name"},
{'id':"age",'help':"Your real age"}
];
for(var i=0;i<helpText.length;i++){
var item = helpText[i];
alert(item.help);
// only to show value of "help" at this point, also to prove that "getHelp()" is
// being called even though the onfocus wasn't used
document.getElementById(item.id).onfocus = getHelp(item.help);
}
}
这里的前提是你有三个输入字段并聚焦它们将返回一个有用的提示(如MDC文章所示)。但是,这是我缺乏把握的关键:如果你在“getHelp()”函数中发出警告(以便测试),并在“setupHelp()”函数中放置一个警告,就在设置bind事件之前对dom元素的引用的处理程序,你会看到,在加载页面时,循环运行,然后是getHelp()函数,然后是循环,然后是getHelp()函数等,直到循环结束。因此,如果getHelp()函数绑定到onfocus事件处理程序,并且您甚至没有聚焦输入字段,那么getHelp()函数可以运行吗? JAvaScript如何从一个小循环中存储所有可能的结果? :S
你能提供的任何帮助都会有所帮助,这是令人难以置信的。我敢肯定它只会点击其中一天,但我很不耐烦。 :P
汤姆。
答案 0 :(得分:1)
因此,如果getHelp()函数绑定到onfocus事件处理程序,并且您甚至不关注输入字段,那么getHelp()函数可以运行吗? JAvaScript如何从一个小循环中存储所有可能的结果?
这是你问题的症结所在,答案就在这里:
for(var i=0;i<helpText.length;i++){
var item = helpText[i];
alert(item.help);
// only to show value of "help" at this point, also to prove that "getHelp()" is
// being called even though the onfocus wasn't used
document.getElementById(item.id).onfocus = getHelp(item.help);
}
那是 JavaScript解释器如何存储所有可能的结果:因为你告诉它它们是什么。你正在调用生成函数的getHelp
,然后返回该函数。
这如何工作比看起来简单得多。 :-)我进入它here,但基本上:当你调用一个函数时,会创建一个叫做执行上下文的东西。这是一个对象(JavaScript是大规模面向对象,直到解释器级别)。在该执行上下文对象中,有一个叫做变量对象的东西。它包含执行上下文的所有变量,作为属性。这包括函数的参数,函数中的所有var
以及任何声明的函数(在您的示例中没有任何声明的函数,因此我们可以忽略那;你只有函数表达式,这很好)。在执行上下文中由表达式声明或定义的任何函数都具有对该执行上下文的变量对象的持久引用,并在调用它时使用它来解析变量引用。
所以:在你的循环中,当你调用getHelp
时,会创建一个对象来存储与该调用相关的数据。该对象绑定到您在调用中创建并存储在onfocus
处理程序上的函数(该函数关闭的数据 [这就是为什么它被称为 >闭合])。当/如果调用处理程序时,就是如何解析函数所持有的引用,而不是该对象的属性。
答案 1 :(得分:0)
实际上,您将getHelp(help)
的结果分配给您的onfocus事件,因此两个警报都显示完全正常,因为执行了getHelp以提供结果。
如果你把警报放在返回者功能中,我很确定你不会看到它:
function getHelp(help){
return function(){
alert(help);
showHelp(help);
}
}