Easy Learning of Javascript Closures

  • 2021-07-26 06:02:13
  • OfStack

Closure (closure) is a difficult and characteristic of Javascript language, and many advanced applications depend on closure.

When function is nested in function, the internal function can access the variables in the external function.


function foo(x) {
 var tmp = 3;
 function bar(y) {
  alert(x + y + (++tmp));
 }
 bar(10);
}
foo(2)

alert 16, no matter how many times it is executed, because bar can access x, a parameter of foo, and tmp, a variable of foo.

However, this is not a closure. When your return is internal function, it is a closure. Internal function will be close-over external function variables until the end of internal function.


function foo(x) {
 var tmp = 3;
 return function (y) {
  alert(x + y + (++tmp));
 }
}
var bar = foo(2); // bar  Now it is 1 Closure 
bar(10);

The script above ends up with alert 16, too, because bar can access x and tmp even though bar is not directly within the inner scope of foo.

However, since tmp still exists inside the bar closure, it still adds 1 to itself, and it adds 1 to itself every time you call bar.

(Considering the 6-year-old limit: we can actually create more than one closure method, such as an array of return, or set them as global variables. They all point to the same x and the same tmp, instead of having one copy each.)

Note: Now let's finish some 7-year-old content.

The above x is a literal value (value passing), and the other literals in JS are similar. When foo is called, the value of the argument x is copied, and the copied one is used as the parameter x of foo.

Then the problem comes. In JS, reference passing is used when dealing with object. Then, when you call foo, you pass an object, and the closure of return of foo function will also refer to the original object!


function foo(x) {
var tmp = 3;
return function (y) {
 alert(x + y + tmp);
 x.memb = x.memb ? x.memb + 1 : 1;
 alert(x.memb);
 }
}
var age = new Number(2);
var bar = foo(age); // bar  Now it is 1 A quote age Closure of 
bar(10);

Not surprisingly, every time bar (10) is run, x. memb adds itself 1. However, it should be noted that x points to the same object variable-age every time. After running bar (10) twice, age. memb will become 2.
This is related to the memory leak of the HTML object, which, uh, seems to be beyond the scope of the answer.

Here is an example of a closure that does not use the return keyword:


function closureExample(objID, text, timedelay) { 
  setTimeout(function() { 
    document.getElementById(objID).innerHTML = text; 
  }, timedelay); 
} 
closureExample( ' myDiv',  ' Closure is created', 500);   

function in JS can access their:

1. Parameters

2. Local variables or functions

3. External variables (environmental variables?) , including

3.1 Global variables, including DOM.

3.2 Variables or functions of external functions.

If a function accesses its external variables, then it is a closure.

Note that external functions are not required. By accessing external variables, a closure can maintain (keep alive) these variables. In the case of internal and external functions, external functions can create local variables and eventually exit; However, if any one or more inner functions do not exit after it exits, then the inner function maintains the local data of the outer function.
A typical example is the use of global variables.

Closures are often used to create functions with hidden data (but not always).


var db = (function() {
//  Create 1 A hidden object,  This object Hold 1 Some data 
//  You can't access this from the outside object Adj. 
var data = {};
//  Create 1 Functions ,  This function provides 1 Some visits data Data method of 
return function(key, val) {
  if (val === undefined) { return data[key] } // get
  else { return data[key] = val } // set
  }
//  We can call this anonymous method 
//  Returns this inner function, which is 1 Closure 
})();

db('x'); //  Return  undefined
db('x', 1); //  Settings data['x'] For 1
db('x'); //  Return  1
//  It is impossible for us to visit data This object Itself 
//  But we can set its members 

Let's take a look at the points to note when 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: