Learning Javascript closure (Closure) knowledge

  • 2021-07-09 07:04:09
  • OfStack

1. Scope of variables

To understand closures, you must first understand the special variable scope of Javascript.

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

The special feature of Javascript language is that global variables can be read directly inside functions.


var n=999;
    function f1(){
          alert(n);
    }
    f1(); // 999

On the other hand, it is naturally impossible to read local variables inside a function outside the function.


   function f1(){
                  var n=999;
        }
        alert(n); // error

There is one place to note that when declaring variables inside a function, 1 must use the var command. If you don't use it, you actually declare 1 global variable!


function f1(){
          n=999;
    }
    f1();
    alert(n); // 999

2. How do I read local variables from outside?

For various reasons, we sometimes need to get local variables in functions. But, as I said earlier, under normal circumstances, this cannot be done, and it can only be achieved through workarounds.

That is 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 inside the function f1, and all the local variables inside f1 are visible to f2. But the reverse is not true. Local variables inside f2 are invisible to f1. This is the unique "chain scope" structure of Javascript language (chain scope), and the child object will look up all the variables of the parent object level by level. Therefore, all variables of the parent object are visible to the child object, otherwise it is not true.

Since f2 can read local variables in f1, we can read its internal variables outside f1 by taking 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 various professional literatures is very abstract and difficult to understand. My understanding is that closures are functions that can read variables inside other functions.
In Javascript language, only sub-functions within a function can read local variables, so closure can be simply understood as "a function defined within a function".

Therefore, in essence, a closure is a bridge connecting the inside and outside of a function.

4. Use of closures

Closures can be used in many places. It has two greatest uses, one is to read the variables inside the function mentioned above, and the other is to keep the values of these variables in memory at all times.

How to understand this sentence? Look at 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 a closure f2 function. It runs twice, the first time with a value of 999 and the second time with a value of 1000. This proves that the local variable n1 in the function f1 is stored in memory and is not automatically cleared after the f1 call.

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

Another notable point in this code is the line "nAdd=function () {n+=1}". First of all, the var keyword is not used before nAdd, so nAdd is a global variable, not a local variable. Secondly, the value of nAdd is an anonymous function (anonymous function), and this anonymous function itself is a closure, so nAdd is equivalent to an setter, which can operate on local variables inside the function outside the function.

5. Notices for using closures

1) Because closures will make the variables in the function are stored in memory, memory consumption is very large, so we can't abuse closures, otherwise it will cause performance problems of web pages, which may lead to memory leakage in IE. The solution is to delete all local variables that are not used before exiting the function.

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


Related articles: