请解释闭包,或将循环计数器绑定到函数范围
我见过程序员使用计数器在循环内分配事件侦听器。我相信这就是语法:
for(var i=0; i < someArray.length; i++){
someArray[i].onclick = (function(i){/* Some code using i */})(i);
}
有人可以解释一下这背后的逻辑吗?这种奇怪的语法,我从未见过:
(function(i))(i);
非常感谢您的时间和耐心。
I've seen programmers assign events listeners inside loops, using the counter. I believe this is the syntax:
for(var i=0; i < someArray.length; i++){
someArray[i].onclick = (function(i){/* Some code using i */})(i);
}
Could someone please explain the logic behind this, and this weird syntax, I've never seen this:
(function(i))(i);
Many thanks for your time and patience.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
(function(i))(i)
语法创建一个匿名函数,然后立即执行它。通常,您将在每次循环时创建一个新函数,该函数具有自己的变量副本,而不是每个事件处理程序共享相同的变量。
举个例子:
经常会让人出局,因为无论你点击哪个按钮,
doFoo(10)
都会被调用。然而:
为每次迭代创建内部函数的新实例(具有其自己的值
i
),并按预期工作。The
(function(i))(i)
syntax creates an anonymous function and then immediately executes it.Usually you'll do this to create a new function every time through the loop, that has its own copy of the variable instead of every event handler sharing the same variable.
So for example:
Often catches people out, because no matter what button you click on,
doFoo(10)
is called.Whereas:
Creates a new instance of the inner function (with its own value of
i
) for each iteration, and works as expected.这样做是因为 JavaScript 只有函数作用域,而不是块作用域。因此,您在循环中声明的每个变量都在函数的范围内,并且您创建的每个闭包都可以访问相同的变量。
因此,创建新作用域的唯一方法是调用函数,这就是
正在做的事情。
请注意,您的示例遗漏了一个重要部分:立即函数必须返回另一个函数,该函数将成为
click
处理程序:立即函数没有什么特别的。它以某种方式内联函数定义和函数调用。您可以将其替换为普通函数调用:
This is done because JavaScript only has function scope, not block scope. Hence, every variable you declare in a loop is in the function's scope and every closure you create has access to the very same variable.
So the only way to create a new scope is to call a function and that is what
is doing.
Note that your example misses an important part: The immediate function has to return another function which will be the
click
handler:The immediate function is nothing special. It is somehow inlining function definition and function call. You can replace it by a normal function call: