在下面的代码片段中,为什么以及如何调用函数形成一个全新的执行上下文,其中保留了i的值?函数保留参数
function getHandler(n) {
return function() {
alert('You clicked on: ' + n);
};
}
for (var i = 0; i < 100; ++i) {
myElements[i].onclick = getHandler(i);
}
在下面的代码片段中,为什么以及如何调用函数形成一个全新的执行上下文,其中保留了i的值?函数保留参数
function getHandler(n) {
return function() {
alert('You clicked on: ' + n);
};
}
for (var i = 0; i < 100; ++i) {
myElements[i].onclick = getHandler(i);
}
它是由JavaScript关闭和JavaScript中for循环中声明的变量的行为引起的。因为参数n
是addHandler
的闭包的一部分,所以n在它自身内部声明的函数实例保持它的值。它恰好是你从全球空间的循环中传入我的。
Here is a fiddle showing that behavior。
如果您要在addHandler
内部增加n
,您会发现它实际上并没有影响i
。再次,这是因为关闭,addHandler
的封闭内存在n
,并且仅由i
填充。
Here is a fiddle showing that behavior。
由于关闭,n
将存在,无论在addHandler
(在这种情况下,某些函数引用)内部创建的任何东西都存在。
我希望这是有道理的。我想,解释很棘手。
编辑:Here is an awesome explanation of JavaScript closures以及它们是如何工作的。
谢谢!这就说得通了。一个函数的“关闭”如何发生?也就是说,当你定义一个返回函数的函数时,该内部函数可以在外部函数的执行时访问外部函数的属性。但只要内函数返回并设置为外函数外的新变量,它如何记住外函数中的变量? –
或者我们总是通过调用外部函数来使用内部函数,所以它总是在外部函数的上下文中执行? –
最好的办法是查看括号{} ...如果某个函数的外部括号内有*声明的内容,它将可用于在这些相同括号内声明的任何其他内容。 –
我假设你的意思是为什么以及如何从循环内调用函数*形成一个全新的...等等等等? –
听起来像某种功课给我。如果不是,那么原因是在创建新的匿名函数时为getHandler函数作用域创建的闭包。然后返回函数引用,并返回由于关闭而保留的值'n'。 – ZenMaster