闭包定义和示例

发布于 2024-09-10 13:48:58 字数 94 浏览 2 评论 0原文

什么是闭包及其对应示例?

我研究了很多,但无法理解。 请从通用编程语言概念方面和特定编程语言方面进行解释。

请帮忙。

谢谢。

what is closure and its correspondence example ?

I have research a lot and could not understand.
Please explain in generic programming language concept aspect and specific programming language aspect.

Please help.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜尕妞 2024-09-17 13:48:58

闭包基本上是一个嵌套在函数 A 中的函数 B,它可以访问 A 的局部变量:

function A() {
    var x = 5;

    function B() {
        print(x);
    }

    return B;
}

如果您有 C++ 背景,那么这是相当难以理解的。当我们尝试调用 A 返回的函数时,它会引用什么x?自从 A() 终止后,x 不会无效吗?

答案是x实际上还存在。我们返回的 B 实际上隐式地带有 x 。很酷,嗯?

从更一般的意义上来说,闭包是绑定到某些数据的函数。在像 C 这样没有闭包的语言中,每个程序都有固定数量的函数。使用闭包,从某种意义上说,您可以通过将函数绑定到动态数据来“创建函数”。当然,没有人会阻止你模仿 C 中的闭包,但有时这可能会很痛苦。

闭包确实很有用。例如,假设我们想要实现我们自己的“for 循环”:

function loop(count, f) {
    for (var i = 0; i < count; i++)
        f(i);
}

var array = [0,1,2,3,4];

loop(5, function(i) {
    print(array[i]);
});

允许访问外部变量而不做一堆额外的废话可以使代码变得漂亮和简单。如果没有闭包,您可能必须将上下文变量传递给 loop 函数:

function loop(count, f, ctx) {
    for (var i = 0; i < count; i++)
        f(i, ctx);
}

var array = [0,1,2,3,4];

loop(5, function(i, ctx) {
    print(ctx[i]);
}, array);

另一个例子:假设我们想在 jQuery 中注册一个回调,但它可能在函数及其调用者和它的调用者的调用者已完成运行:

$(document).ready(function(){

    var clicked = 0;

    $('#button').click(function(){
        clicked++;
        alert("You've pressed the button " + clicked + " times.");
    });

});

如果 JavaScript 更像 C++(在 C++0x 之前),则在将函数赋予 $(document) 时,那个 clicked 变量早就消失了。调用了ready(),并且按钮单击回调将具有未定义的行为。

A closure is basically a function B nested inside a function A that can access A's local variables:

function A() {
    var x = 5;

    function B() {
        print(x);
    }

    return B;
}

If you come from a C++ background, this is rather hard to digest. When we try to call the function returned by A, what x will it refer to? Won't that x be invalid since A() terminated?

The answer is that x actually lives on. That B we returned actually carries x around with it implicitly. Cool, eh?

In a more general sense, a closure is a function bound to some data. In a language without closures like C, every program has a fixed number of functions. With closures, you can, in a sense, "create functions" by binding them to dynamic data. Of course, nobody's stopping you from emulating closures in C, but it can be a pain sometimes.

Closures are really useful. For instance, suppose we want to implement our own "for loop":

function loop(count, f) {
    for (var i = 0; i < count; i++)
        f(i);
}

var array = [0,1,2,3,4];

loop(5, function(i) {
    print(array[i]);
});

Being allowed to access outside variables without doing a bunch of extra nonsense keeps code nice and simple. Without closures, you might have to pass a context variable to the loop function instead:

function loop(count, f, ctx) {
    for (var i = 0; i < count; i++)
        f(i, ctx);
}

var array = [0,1,2,3,4];

loop(5, function(i, ctx) {
    print(ctx[i]);
}, array);

Another example: suppose we want to register a callback in jQuery, but it may be executed long after the function and its caller and its caller's caller are done running:

$(document).ready(function(){

    var clicked = 0;

    $('#button').click(function(){
        clicked++;
        alert("You've pressed the button " + clicked + " times.");
    });

});

If JavaScript were more like C++ (before C++0x), that clicked variable would be long gone by the time the function given to $(document).ready() was called, and the button clicking callback would have undefined behavior.

写下不归期 2024-09-17 13:48:58

这是我对闭包的看法......

函数对象由两部分组成。第一件事是函数的代码,第二件事是它执行的范围。在闭包中,函数执行的范围和代码是相互分离的。相同的代码可以在不同的范围内执行。

如果以完全不受限制的方式允许这样做,将会导致极大的混乱。即使它像动态作用域一样松散(函数继承了调用它的地方的作用域),它也会变得非常混乱。

闭包是指定范围规则的一种便捷方式,这种方式很有意义,因为它们只需要读取代码而不需要跟踪它。在闭包中,函数获得声明它的范围。如果在执行另一个函数时声明它,它将获取该函数堆栈的特定实例的范围。这比能够给出闭包和任意作用域或动态作用域要简单得多,更容易理解。

下面是 Python 中一个普通闭包的示例:

def outer():
    def closure():
        pass
    return closure

这里的函数 closure 是一个闭包。它实际上并没有使用定义它的范围中的任何变量,因此它非常简单,但它仍然是一个。

这是 Python 中的一个不那么简单但仍然简单的闭包:

 def outer(x):
      def closure():
          return x
      return closure
 f1 = outer(5)
 f2 = outer(6)

调用 f1() 将返回 5,调用 f2() 将返回 6。如您所见,函数closure 是部分代码和部分作用域。

当调用 outer(5) 时,它会为调用创建一个堆栈条目,其中包含保存值 5 的变量 x 的版本。然后它声明函数 closure 获取该范围。

当调用 outer(6) 时,它会为该调用创建一个堆栈条目,其中包含保存值 6 的变量 x 的版本。然后它声明函数 closure 获取该范围。

Here is how I think of a closure....

A function object consists of two things. The first thing is the code for the function, the second is the scope in which it executes. In a closure, the scope in which the function executes and the code are detached from each other. The same code can execute in a variety of scopes.

If this were allowed in a completely unrestricted way it would result in great confusion. Even when it's something as loose as dynamic scoping (the function inherits the scope of the place where it was called from) it becomes very confusing.

Closures are a convenient way of specifying scope rules that make a lot of sense because they only require reading the code instead of tracing it. In a closure, the function gets the scope of where it was declared. If it was declared while executing another function, it gets the scope of that specific instance of the function's stack. This is a lot simpler and easier to understand than being able to give the closure and arbitrary scope, or dynamic scoping.

Here is an example of a trivial closure in Python:

def outer():
    def closure():
        pass
    return closure

Here the function closure is a closure. It doesn't actually use any variables from the scope in which it was defined, so it's pretty trivial, but it still is one.

Here is a not-so-trivial, but still simple closure in Python:

 def outer(x):
      def closure():
          return x
      return closure
 f1 = outer(5)
 f2 = outer(6)

Calling f1() will return 5 and calling f2() will return 6. As you can see, the function closure is part code, and part scope.

When outer(5) is called, it creates a stack entry for the call that contains a version of the variable x holding the value 5. It then declares the function closure which gets that scope.

When outer(6) is called, it creates a stack entry for the call that contains a version of the variable x holding the value 6. It then declares the function closure which gets that scope.

只是偏爱你 2024-09-17 13:48:58

如果您想要有关闭包的示例,我建议您查看这本书

深入 Python:第 6 章 - 闭包和闭包。生成器

这本书是开放且免费的,您可以在--->下载它。 http://diveintopython3.org/

这个例子很有趣,清晰,并且逐渐采用了更高级的方法。
我认为第一次曝光非常棒。

看看它,没有理由在这里复制它,只要您可以简单地下载或在线阅读即可。

If you want an example on closures i suggest you to check the book

Dive into Python: Chapter 6 - Closures & Generators

The book its open&free and you can download it at---> http://diveintopython3.org/

The example it's interesting,clear and gradually takes a more advanced approach.
For first exposure its great i think.

Take a look at it there is no reason to reproduce it here as long as you can simply download it or read it online.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文