What is a 'Closure'?

前端 未结 23 1679
星月不相逢
星月不相逢 2020-11-22 08:02

I asked a question about Currying and closures were mentioned. What is a closure? How does it relate to currying?

23条回答
  •  南方客
    南方客 (楼主)
    2020-11-22 08:50

    Closures provide JavaScript with state.

    State in programming simply means remembering things.

    Example

    var a = 0;
    
    a = a + 1; // => 1
    a = a + 1; // => 2
    a = a + 1; // => 3
    

    In the case above, state is stored in the variable "a". We follow by adding 1 to "a" several times. We can only do that because we are able to "remember" the value. The state holder, "a", holds that value in memory.

    Often, in programming languages, you want to keep track of things, remember information and access it at a later time.

    This, in other languages, is commonly accomplished through the use of classes. A class, just like variables, keeps track of its state. And instances of that class, in turns, also have state within them. State simply means information that you can store and retrieve later.

    Example

    class Bread {
      constructor (weight) {
        this.weight = weight;
      }
    
      render () {
        return `My weight is ${this.weight}!`;
      }
    }
    

    How can we access "weight" from within the "render" method? Well, thanks to state. Each instance of the class Bread can render its own weight by reading it from the "state", a place in memory where we could store that information.

    Now, JavaScript is a very unique language which historically does not have classes (it now does, but under the hood there's only functions and variables) so Closures provide a way for JavaScript to remember things and access them later.

    Example

    var n = 0;
    var count = function () {
      n = n + 1;
      return n;
    };
    
    count(); // # 1
    count(); // # 2
    count(); // # 3
    

    The example above achieved the goal of "keeping state" with a variable. This is great! However, this has the disadvantage that the variable (the "state" holder) is now exposed. We can do better. We can use Closures.

    Example

    var countGenerator = function () {
      var n = 0;
      var count = function () {
        n = n + 1;
        return n;
      };
    
      return count;
    };
    
    var count = countGenerator();
    count(); // # 1
    count(); // # 2
    count(); // # 3
    

    This is fantastic.

    Now our "count" function can count. It is only able to do so because it can "hold" state. The state in this case is the variable "n". This variable is now closed. Closed in time and space. In time because you won't ever be able to recover it, change it, assign it a value or interact directly with it. In space because it's geographically nested within the "countGenerator" function.

    Why is this fantastic? Because without involving any other sophisticated and complicated tool (e.g. classes, methods, instances, etc) we are able to 1. conceal 2. control from a distance

    We conceal the state, the variable "n", which makes it a private variable! We also have created an API that can control this variable in a pre-defined way. In particular, we can call the API like so "count()" and that adds 1 to "n" from a "distance". In no way, shape or form anyone will ever be able to access "n" except through the API.

    JavaScript is truly amazing in its simplicity.

    Closures are a big part of why this is.

提交回复
热议问题