我知道闭包是什么,但我仍然不明白为什么(或何时)你会使用它们
我对闭包的理解是,它们本质上是一个使用您认为超出范围的变量的函数。我想这是我前几天看到的一个例子:
function closureMaker(somearg)
{
var local_value = 7;
function funcToReturn(arg1, arg2)
{
return local_value + somearg + arg1 + arg2;
}
return funcToReturn;
}
var myClosure = closureMaker(6); //make the closure
myClosure(2, 3); //using it
现在闭包有 local_value 甚至原始的 arg,somearg。但我不明白为什么这些有帮助。使用“自由”变量 local_value 的意义是什么,或者我更不知道,为什么要在闭包函数中使用closureMaking函数的参数?
我更感兴趣的是如何在 javascript 中使用它,这是否经常用于 AJAX 请求和对象?
我明白了什么。我需要知道为什么。
My understanding of closures is that they are essentially a function which uses a variable that you would assume would be out of scope. I guess heres an example I saw the other day:
function closureMaker(somearg)
{
var local_value = 7;
function funcToReturn(arg1, arg2)
{
return local_value + somearg + arg1 + arg2;
}
return funcToReturn;
}
var myClosure = closureMaker(6); //make the closure
myClosure(2, 3); //using it
Now the closure has local_value and even the original arg, somearg. But I dont get why these are helpful. What is the point of using the 'free' variable local_value or even more unknown to me, why would you use the argument of closureMaking function in your closure function?
I'm more interested in how this is used in javascript, Is this used a lot for AJAX requests and objects?
I got the what. I need the why.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
除了上述闭包之外,还有助于隐藏一些实现细节。
还有一篇好文章
阅读这篇关于 javascript 中大量使用闭包的模块模式的文章。
In addition to above closure helps in hiding some of the implementation detail.
One more good article
Read this article on module pattern in javascript which heavily uses closures.
闭包是创建依赖于参数的函数的简单方法。或者换句话说,根据某些运行时值创建函数系列的特定实例(如果不清楚,请继续阅读)。
Javascript 允许您将函数作为一流成员传递;例如,您可以传递一个函数,该函数通过直接引用来确定如何组合两个整数。
然而,更进一步,闭包允许您创建函数的“定制”版本,其确切行为取决于某些运行时变量(但在其他方面符合框架)。
例如,这里有一个允许 柯里化 添加的函数:
现在,如果您调用
getAddNFunction(7)
,您将获得一个将 7 添加到参数的函数。如果调用getAddNFunction(42.5)
,您将获得一个将 42.5 添加到参数的函数。希望这个简单的例子能够阐明闭包的好处;它们允许您在创建时将参数嵌入到函数中,而不必在执行时传入参数(毕竟,调用 getAddNFunction(9)(2) 是与调用
9 + 2
完全相同,除了两个参数可以在非常不同的时间提供这一事实)。例如,您可能想要返回某种相对于某个根元素的复杂 XML 解析函数;闭包允许您将根元素定义嵌入到函数本身中,而不是依赖于调用者在想要执行函数时可以访问它。
Closures are an easy way to make functions that depend on parameters. Or to put it another way, to create a specific instance of a family of functions (read on if that's not clear) depending on some run-time value.
Javascript lets you pass functions around as first-class members; so for example, you could pass around a function that determines how to combine two integers by referring to it directly.
However, going one step further, a closure lets you create a "customised" version of a function, whose exact behaviour depends on some runtime variable (but which otherwise conforms to a framework).
For example, here's a function that will allow a curried addition:
Now if you call
getAddNFunction(7)
, you get a function that adds 7 to an argument. If you callgetAddNFunction(42.5)
, you get a function that adds 42.5 to the argument.Hopefully this simple example clarifies the benefit of closures; they allow you to embed arguments in the function at creation time rather than them having to be passed in at execution time (after all, calling
getAddNFunction(9)(2)
is exactly the same as calling9 + 2
, except for the fact that the two arguments can be supplied at very different times).So for instance you might want to return some kind of complex XML parsing function relative to some root element; a closure lets you embed that root element definition within the function itself, rather than depend on the caller having access to it whenever they want to execute the function.
如果您来自 OO 世界,闭包允许您为对象创建本质上私有的成员变量和方法:
Douglas Crockford 和 javascript 的优点
If you are comnig from an OO world, closures allow you to create what are essentially private member variables, and methods, for your objects:
Douglas Crockford and javascript goodness
这可能不完全是您正在寻找的内容,但是有一篇关于 Java 闭包(它们应该/可以如何实现)的精彩讨论,其中还介绍了一些关于您想要在何处使用它们的示例
http://www.youtube.com/watch?v=0zVizaCOhME
This is probably not quite what you are looking for but there is an excellent talk about closures for Java (how they should/could be implemented) that also goes into some examples on where you would want to use them
http://www.youtube.com/watch?v=0zVizaCOhME
您正在查看的示例试图向您展示闭包的工作原理。我认为闭包是可以传递的小代码片段。巧妙的是,闭包中的(自由)变量是根据当前词法范围进行绑定的。这就是
local_value
保留值7
的原因,因为这是创建闭包时local_value
的值。Javascript 通过闭包实现。 org/wiki/Anonymous_function" rel="nofollow noreferrer">匿名函数*,但请记住,从技术上讲,这是两个不同的概念。
在 Javascript 上下文中,当您想要处理异步发生的事情时,闭包(作为匿名函数实现)非常有用;一个很好的例子是,正如您所说,AJAX 请求您无法预测何时会从服务器收到响应。在本例中,您有一个名为回调的匿名函数,您最初定义该函数并在进行 AJAX 调用时传入该函数。当调用成功完成时,将调用您的回调来处理结果。闭包会产生更干净的代码,因为您可以将行为和逻辑封装在其中。它还可以帮助您抽象我们的行为和单独的关注点。
匿名函数/闭包的另一个用途是事件处理。当事件发生时,您的事件处理程序将被调用。
就像我之前提到的,您可以抽象行为和逻辑并将其放入闭包中。但是真正使闭包如此强大的是上下文。您可以根据创建闭包的环境来自定义闭包的行为。这使得您的函数非常通用,因为您在创建函数时定义其参数(这将影响其行为),而不是在执行期间调用它(使用显式参数)。
这是一篇关于 Javascript 中的闭包的好文章。它很长,但内容丰富:
* As CMS 提到,命名 函数的行为类似于匿名 函数,因为它们可以访问在同一词法范围(或链上的任何内容)中定义的变量。这在内部函数中最为明显。但如果你仔细想想,任何函数都会发生同样的情况;您可以访问已在全局范围内定义的变量(即全局变量)。
The example you're looking at is trying to show you how closures work. I think of closures as little pieces of code that you can pass around. The neat thing is that (free) variables in the closure are bound based on the current lexical scope. This is why
local_value
keeps the value7
because that's what the value oflocal_value
was when the closure was created.Javascript implements closures via anonymous functions*, but keep in mind that technically, these are two separate concepts.
In the context of Javascript, closures (implemented as anonymous functions) are very helpful when you want to deal with things that happen asynchronously; a good example is, like you stated, AJAX requests where you cannot predict when you will get a response back from a server. In this case, you have an anonymous function called a callback that you initially define and pass in when you make the AJAX call. When the call successfully completes, your callback is called to process the result. Closures result in cleaner code since you can package behavior and logic inside them. It also helps you abstract the behavior our and separate concerns.
Another use for anonymous functions/closures is for event handling. When an event happens your event handler is called.
Like I had mentioned before, you can abstract behavior and logic and put it in a closure. But what really makes a closure so powerful is context. You can customize the behavior of your closure, depending on the environment in which it was created. This makes your function very versatile, because you are defining its arguments (which will influence its behavior) while you are creating it, instead of when you are calling it (with explicit parameters) during execution.
Here is a good article about closures in Javascript. It's long, but informative:
* As CMS mentioned, named functions will behave like anonymous functions because they will have access to variables that are defined in the same lexical scope (or anything up the chain). This is most evident in inner functions. But if you think about it, the same happens for any function; you have access to variables that have been defined in the global scope (i.e., global variables).
一个常见的问题是,在 for 循环中,您想要提醒计数器的数量。
当您点击这些链接时,它会警告
5
,因为循环已经完成,并且i
等于5
。我们没有在执行 for 循环时“保存”i
的状态。我们可以创建一个闭包来“保存”该状态:
i
绑定到循环中每个增量中调用的自执行匿名函数。这样状态就被保存了,我们得到了正确的警报#。A common run-in is that in a for loop, you want to alert the number of the counter.
When you go to click on these links, it will alert
5
because the loop has already been done andi
is equal to5
. We didn't "save" the state ofi
at the time of execution of the for loop.We can make a closure to "save" that state:
The
i
is bound to the self executing anonymous functions invoked within each increment in our loop. This way the state is saved and we get the right # on alert.闭包最实用且广泛传播的用法之一是实现 private或特权成员,例如:
模块模式也是一个很好的例子,可以使用相同的原理,例如:
One of the most practical and widely spread usage of closures is to implement private or privileged members for example, for example:
The module pattern is also a good example that can use the same principle, e.g.: