First, the concept of closures:
A closure is an expression (usually a function) that has many variables and an environment in which these variables are bound, so these variables are also part of the expression. In layman's terms, all the function in JS is a closure, but the nested function produces a more powerful closure, which is what we call closures most of the time.
Second, the closure of the microcosm:
To understand the relationship between closures and function A and nested function B in depth, we need to understand the concept of the function execution Environment (excution content), the active object (call object), scope (scope), and scope chain (scope chain). Take function A from definition to execution as an example to illustrate these concepts:
When defining function A, the JS interpreter sets the scope chain of function A to "the environment where a is defined when a is", and if A is a global function, only the Window object is in the scope chain;
When function A is executed, a will enter the appropriate execution environment;
In the process of creating an execution environment, you first add a scope property to the function, that is, the scope of a, whose value is the scope chain in the first step, that is, the scope chain of the a.scope=a;
The execution environment then creates an active object. The active object also has a Property object, but it does not have a prototype and cannot be accessed directly through JavaScript. After the active object is created, add the active object to the top of the scope chain of a. At this point A's scope chain contains two objects: A's active object and the Window object;
The next step is to add a arguments property on the active object, which holds the arguments passed when the function A is called.
Finally, the reference of all function A's parameters and internal function B is added to the active object of a. In this step, the definition of function B is completed, so as in the third step, the scope chain of function B is set to the environment defined by B, which is the scope of a.
This completes the entire function A from definition to execution. At this point a returns a reference to function B to C, and the scope chain of function B contains a reference to the active object of function A, which means that B can access all the variables and functions defined in a. Function B is referenced by C and function B has a dependency on function A, so function A will not be acquired by GC after it returns.
Third, the function of the closure function:
1. Anonymous execution function
We know all the variables, and if we don't add the var keyword, the default will be added to the properties of the global object, so that the temporary variables added to the global object will have a lot of disadvantages, such as: Other variables may be useless these variables, causing the global object is too large, Affects access speed (because the values of variables need to be traversed from the prototype chain).
In addition to using the VAR keyword every time a variable is used, we also encounter a situation in the actual usage situation where a function is executed only once and its internal variables are not maintained. For example, the initialization of the UI, we can use closures:
var Datamodel = { table: [], tree: {} }; (function (DM) {for (var i = 0; i < dm.table.rows; i++) { var row = dm.table.rows[i]; for (var j = 0; j < Row.cells; i++) { Drawcell (i, j); } } Build Dm.tree
An anonymous function is created in the appeal code and executed immediately, since the external cannot reference its internal variables, so it will be released shortly after execution, the key being that this mechanism does not pollute the global object.
2. Caching
If we have a very time-consuming function object, each call takes a very long period, then we will store the computed value, and when this function is called, it is first looked up in the cache, if not found, then the cache is updated and the value is returned, if found, Return directly to the value you are looking for. Closures are exactly what you can do, so it does not release external references, so values inside the function can be preserved.
var Cachedsearchbox = (function () {var cache = {}, Count = []; return {attachsearchbox:function (DSID) {if (Dsid in cache) {//If the result is in the cache Return cache[dsid];//directly returns the object in the cache} var FSB = new Uikit.webctrl.SearchBox (DSID);//New CACHE[DSID] = fsb;//Update cache if (Count.length > 100) {//Yasumasa cache size <=100 Delete Cache[count.shift ()]; } return FSB; }, Clearsearchbox:function (DSID) {if (Dsid in cache) {cache [Dsid].clearselection (); } } }; })(); Cachedsearchbox.attachsearchbox ("input1");
So, when we call Cachedsearchbox.attachserachbox ("INPUT1") for the second time,
Instead of creating a new SearchBox object, we can take the object from the cache.
3. Implementing encapsulation
Internal variables cannot be accessed outside the function, but can be accessed in the form of closures.
var person = function () { //variable scope is inside function, external cannot access var name = "Default"; return { getname:function () { return name; }, setname:function (newName) { name = NewName; } } } (); Print (person.name);//Direct access with the result of undefined print (Person.getname ()); Person.setname ("Abruzzi"); Print (Person.getname ()); The results are as follows: undefined default Abruzzi
4. Implementing Object-oriented objects
Traditional object languages provide a template mechanism for classes so that different objects (instances of classes) have independent members and states, without interfering with each other, although there is no such mechanism in JavaScript, we can simulate such mechanisms by closures.
function person () { var name = "Default"; return { getname:function () { return name; }, setname:function (newName) { name = NewName; } } }; var john = person (); Print (John.getname ()); John.setname ("John"); Print (John.getname ()); var jack = person (); Print (Jack.getname ()); Jack.setname ("Jack"); Print (Jack.getname ()); The results of the operation are as follows: default John default Jack
In the above code, both John and Jack can be referred to as instances of the person class, because these two instances have independent, non-impact access to name.
Iv. JavaScript garbage collection mechanism
In JavaScript, if an object is no longer referenced, the object is recycled by the GC. If two objects are referenced by each other and are no longer referenced by a third party, then the two objects referenced by each other are also recycled.
Closures are a high-level application in JavaScript and a must for advanced JS programmers, understanding their interpretation and operational mechanisms to write more secure and elegant code.
JS Closed Package