我知道闭包是什么,但我仍然不明白为什么(或何时)你会使用它们

发布于 2024-09-13 04:36:39 字数 573 浏览 3 评论 0原文

我对闭包的理解是,它们本质上是一个使用您认为超出范围的变量的函数。我想这是我前几天看到的一个例子:

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 技术交流群。

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

发布评论

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

评论(7

尾戒 2024-09-20 04:36:49

除了上述闭包之外,还有助于隐藏一些实现细节。

var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }   
})();

alert(Counter.value()); /* Alerts 0 */
Counter.increment();
Counter.increment();
alert(Counter.value()); /* Alerts 2 */
Counter.decrement();
alert(Counter.value()); /* Alerts 1 */

还有一篇好文章

阅读这篇关于 javascript 中大量使用闭包的模块模式的文章。

In addition to above closure helps in hiding some of the implementation detail.

var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }   
})();

alert(Counter.value()); /* Alerts 0 */
Counter.increment();
Counter.increment();
alert(Counter.value()); /* Alerts 2 */
Counter.decrement();
alert(Counter.value()); /* Alerts 1 */

One more good article

Read this article on module pattern in javascript which heavily uses closures.

最单纯的乌龟 2024-09-20 04:36:46

闭包是创建依赖于参数的函数的简单方法。或者换句话说,根据某些运行时值创建函数系列的特定实例(如果不清楚,请继续阅读)。

Javascript 允许您将函数作为一流成员传递;例如,您可以传递一个函数,该函数通过直接引用来确定如何组合两个整数。

然而,更进一步,闭包允许您创建函数的“定制”版本,其确切行为取决于某些运行时变量(但在其他方面符合框架)。

例如,这里有一个允许 柯里化 添加的函数:

function getAddNFunction(n)
{
    function inner(operand)
    {
        return n + operand;
    }
    return inner;
}

现在,如果您调用 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:

function getAddNFunction(n)
{
    function inner(operand)
    {
        return n + operand;
    }
    return inner;
}

Now if you call getAddNFunction(7), you get a function that adds 7 to an argument. If you call getAddNFunction(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 calling 9 + 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.

猫腻 2024-09-20 04:36:46

如果您来自 OO 世界,闭包允许您为对象创建本质上私有的成员变量和方法:

function Constructor(...) {
  var privateVar = value;
  function privateFunc() {
  }
  this.publicFunc = function() {
  // public func has access to privateVar and privateFunc, but code outside Constructor does not
  }
}

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:

function Constructor(...) {
  var privateVar = value;
  function privateFunc() {
  }
  this.publicFunc = function() {
  // public func has access to privateVar and privateFunc, but code outside Constructor does not
  }
}

Douglas Crockford and javascript goodness

人事已非 2024-09-20 04:36:45

这可能不完全是您正在寻找的内容,但是有一篇关于 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

缱倦旧时光 2024-09-20 04:36:44

您正在查看的示例试图向您展示闭包的工作原理。我认为闭包是可以传递的小代码片段。巧妙的是,闭包中的(自由)变量是根据当前词法范围进行绑定的。这就是 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 value 7 because that's what the value of local_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).

无言温柔 2024-09-20 04:36:41

一个常见的问题是,在 for 循环中,您想要提醒计数器的数量。

function addLinks () {
    for(var i = 0; i < 5; ++i) {
        var link = document.createElement('a');
        link.appendChild(document.createTextNode('Link ' + i));
        link.i = i;
        link.onclick = function() { alert( i ) };
        document.body.appendChild(link);
    }
}

addLinks();

当您点击这些链接时,它会警告 5,因为循环已经完成,并且 i 等于 5。我们没有在执行 for 循环时“保存”i 的状态。

我们可以创建一个闭包来“保存”该状态:

function addLinks () {
    for(var i = 0; i < 5; ++i) {
        var link = document.createElement('a');
        link.appendChild(document.createTextNode('Link ' + i));
        link.i = i;
        link.onclick = (function(i) { return function() {  alert(i ) } })(i);
        document.body.appendChild(link);
    }
}

addLinks();

i 绑定到循环中每个增量中调用的自执行匿名函数。这样状态就被保存了,我们得到了正确的警报#。

A common run-in is that in a for loop, you want to alert the number of the counter.

function addLinks () {
    for(var i = 0; i < 5; ++i) {
        var link = document.createElement('a');
        link.appendChild(document.createTextNode('Link ' + i));
        link.i = i;
        link.onclick = function() { alert( i ) };
        document.body.appendChild(link);
    }
}

addLinks();

When you go to click on these links, it will alert 5 because the loop has already been done and i is equal to 5. We didn't "save" the state of i at the time of execution of the for loop.

We can make a closure to "save" that state:

function addLinks () {
    for(var i = 0; i < 5; ++i) {
        var link = document.createElement('a');
        link.appendChild(document.createTextNode('Link ' + i));
        link.i = i;
        link.onclick = (function(i) { return function() {  alert(i ) } })(i);
        document.body.appendChild(link);
    }
}

addLinks();

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.

故笙诉离歌 2024-09-20 04:36:40

闭包最实用且广泛传播的用法之一是实现 private特权成员,例如:

function Test (param) {
  var secret = 3;
  function privateMethod() {
    //...
  }
  this.publicMember = param;
  this.privilegedMember = function () {
    return secret * param;
  };
}

var foo = new Test(10);
foo.privilegedMember(); // 30
foo.secret; // undefined

模块模式也是一个很好的例子,可以使用相同的原理,例如:

var myModule = (function () { 
  var obj = {}, privateVariable = 1; 

  function privateMethod() { 
    // ... 
  } 

  obj.publicProperty = 1; 
  obj.publicMethod = function () { 
    // private members available here... 
  }; 

  return obj; 
}());

One of the most practical and widely spread usage of closures is to implement private or privileged members for example, for example:

function Test (param) {
  var secret = 3;
  function privateMethod() {
    //...
  }
  this.publicMember = param;
  this.privilegedMember = function () {
    return secret * param;
  };
}

var foo = new Test(10);
foo.privilegedMember(); // 30
foo.secret; // undefined

The module pattern is also a good example that can use the same principle, e.g.:

var myModule = (function () { 
  var obj = {}, privateVariable = 1; 

  function privateMethod() { 
    // ... 
  } 

  obj.publicProperty = 1; 
  obj.publicMethod = function () { 
    // private members available here... 
  }; 

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