Javascript closure (Closure) in detail

  • 2020-06-07 03:57:39
  • OfStack

Below are my study notes, which should be useful for Javascript beginners.

1. Scope of variables

To understand closures, you must first understand Javascript's special variable scope.

The scope of variables is nothing more than two kinds: global variables and local variables.

What makes the Javascript language special is that global variables can be read directly from within functions.


var n=999;

function f1(){
  alert(n);
}

f1(); // 999

On the other hand, local variables within a function cannot naturally be read outside the function.


function f1(){
  var n=999;
}

alert(n); // error

One thing to note here is that when declaring variables within a function, 1 must use the var command. If you don't, you're actually declaring a global variable!


function f1(){
  n=999;
}

f1();

alert(n); // 999

2. How to read local variables from outside?

For a variety of reasons, we sometimes need to get local variables within a function. However, as stated earlier, this is not normally possible and can only be achieved through workarounds.

So I'm going to define another function inside the function.


function f1(){

  var n=999;

  function f2(){
    alert(n); // 999
  }

}

In the above code, the function f2 is included within the function f1, where all local variables within f1 are visible to f2. But the other way around, local variables inside f2 are not visible to f1. This is the "chain-scope" structure characteristic of the Javascript language (chain scope), in which the child object looks up, level by level, for all the parent object's variables. Therefore, all variables of the parent object are visible to the child object, and vice versa.

Since f2 can read local variables in f1, we can read its internal variables outside of f1 by using f2 as the return value.


function f1(){

  var n=999;

  function f2(){
    alert(n); 
  }

  return f2;

}

var result=f1();

result(); // 999

3. The concept of closures

The f2 function in the previous section is a closure.

The definition of "closure" (closure) in the various professional literature is very abstract and hard to understand. My understanding is that closures are functions that can read variables inside other functions.

Because in Javascript, local variables can only be read by subfunctions within a function, you can think of closures simply as "functions defined within a function."

So, in essence, a closure is a bridge between the inside and outside of a function.

4. The purpose of closures

Closures can be used in many ways. It is useful for two reasons, one is to read variables inside a function, and the other is to keep the values of those variables in memory.

How to understand this sentence? See the code below.


  function f1(){

    var n=999;

    nAdd=function(){n+=1}

    function f2(){
      alert(n);
    }

    return f2;

  }

  var result=f1();

  result(); // 999

  nAdd();

  result(); // 1000

In this code, result is actually the closure f2 function. It runs 1 twice, 999 the first time, 1000 the second time. This proves that the local variable n1 in the function f1 is kept straight in memory and is not automatically cleared after the call to f1.

Why is that? The reason is that f1 is the parent function of f2 and f2 is assigned to a global variable, which causes f2 to always be in memory, and f2's existence depends on f1, so f1 is always in memory and is not collected by the garbage collection mechanism (garbage collection) after the call.

Another notable feature in this code is the line "nAdd=function(){n+=1}", which first does not use the var keyword before nAdd, so nAdd is a global variable rather than a local variable. Second, the value of nAdd is an anonymous function (anonymous function), and the anonymous function itself is a closure, so nAdd is equivalent to an setter to operate on local variables inside the function outside of the function.

5. Note the use of closures

1) Because closures cause variables in functions to be kept in memory, which consumes a lot of memory, closures cannot be abused, which can cause performance problems for web pages and may cause memory leaks in IE. The solution is to remove all unused local variables before exiting the function.

2) Closures change the values of variables inside the parent function, outside of the parent function. So, if you use a parent function as an object (object), a closure as its public method (Public Method), and an internal variable as its private property (private value), be careful not to change the value of the parent function's internal variable.

6. Consider

If you understand the results of the following two pieces of code, you should understand how closures work.

Code snippet 1


  var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      return function(){
        return this.name;
      };

    }

  };

  alert(object.getNameFunc()());

Code snippet 2


  var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };

    }

  };

  alert(object.getNameFunc()());   

This is the end of this article, I hope you enjoy it.


Related articles: