Sharing a know almost straightforward answer to the most detailed closure js

Author: Big hairy idler Chai
Link: https: //www.zhihu.com/question/34210214/answer/136673471
Source: know almost
Copyright reserved by the authors. Commercial reprint please contact the author authorized, non-commercial reprint please indicate the source.
Closure is another large core JS language, if fully understood from the perspective of memory closures, I suggest that you first rehearsal under the previous few speaking blog:
Moving steadily JavaScript (a) - Scope chain
Steady JavaScript (II) - illustrated Object Model Memory
Moving steadily JavaScript (three) - several ways to create objects
What is the definition of closure
A closure is a function of access to other functions scope.
This sentence may seem hard to pronounce, If you read the previous few blog, it should not be difficult to understand. Let's resolve what this sentence:
* First, the closure is a function;
* Second, this function can not only access its own scope, more critical is that it can access the scope of other functions.
In other words, if a function other functions can access the variable scope, then this function is called "closure."
How to create a closure?
As long as further defines a function in a function, the function is an internal closure.
Note: as long as a function of the conditions inside another function, this function is internal closure, regardless of how this internal function is present in the form of the outer function. Here are a few examples:
* A form:
function father () {
    function son () {
    }
}
* In the form of two:
function father () {
    var object = new Object();
    object.son = function () {
    }
}
* In the form of three:
function father () {
    var object = {
        son : function(){}
    };
}
Internal functions as defined above are three forms of closure.
* A form: in one function and one function is defined, it is entirely consistent with the definition of closure, needless to say.
* Form of two: a function to create an object, and then define a function inside the object, this is closure.
* Three forms: the form of two essentially the same, but also to define an object inside the function, then the object is defined within a closure. But the object is defined manner and form two differ.
Closure What is the use?
Previously defined closure, said "the closure of other functions can access the variable scopes." "Other Functions" refers to the function of the outer closure is located.
In other words, the closure can access it all the variables in the outer function, even if the outer function has been carried over.
This feature will help us to achieve closure of some of the features in the object-oriented JavaScript door this non-object-oriented languages. This will be described in detail later.
Closed principle of the package
Principle closures related to the scope chain of memory model, here with us recap the scope chain, more detailed content please see: slow and steady JavaScript (a) - Scope chain
The following code as an example:
function father () {
    var name = "Dad";
    var company = "Google";
    function son () {
        var name = "son";
        var school = "Qidong Middle";
        alert(name);
        alert(school);
    }
    return son;
}
This code defines a window function scope Father;
father has two local variables: name, company;
father defines a closure;
Closure defines two local variables: name, school.
* When initialization is complete JS:
Four things associated with the emergence of the global environment in memory:
    1. The object of the global environment variable (variable storage for the global environment, such as: father function)
    2. Scope and global environment scope chain (scope chain is a chain composed of multiple scopes, the scope chain in only one of the global environment scope of the global environment, the object it points to the global environment variable)
    3. execution environment and the global environment stack execution environment (the execution environment stored inside a stack execution environment stack indicates that the environment is being executed. Execution environment has a pointer to its scope chain)
    4. father scope chain function (in this case a function of father scope chain contains only the scope of the global environment, and their function is no scope father)
Note: Each function their scope is created when the function is executed, and the function scope chain is created when the environment where the function is executed. When a function is executed, its own scope will be added to the head of the scope chain has been created.
* When executing father function:
JS engine will create the above four things for it:
    1. A variable objects belonging to it (which kept name, company, son)
    2. a part of its scope chain
At this time, the scope chain comprises two scopes, namely: Scope father global scope and function, they point to the respective variable object;
    3. A part of his execution environment, and the execution environment onto stack execution environment stack;
    4. scope chain son function (which contains the global environment and scope father)
At this time, the memory is as follows:
* When the father function execution ends:
After the end of the function is executed, its execution environment and the scope chain will be destroyed, and its variable object depends on whether there are references to it.
Since the function pointed son scope chain variable objects father, so it remains resident in memory.
* When performing son functions:
The same, JS son as a function of the engine will successively create these things, and the scope of the function new son pressed into the head of the scope chain, when the memory is as follows:
* When performing alert (company):
JS engine will in turn find the value of variable objects in the scope chain son along function.
Find Start with son variable object, if the object is not variable, the variable continues to find the father objects along the scope chain, once found, to stop.
Therefore, if it can find name, first of all to find the son variable object, find the stop, because there is no access to the father in the name, whether or delete name unless the son function deletes son in name.
Principle closures summary
In summary, the closure is able to access the variable scope of its outer function, because the variable object is a function of the presence of the outer closure of the scope chain. Even if the outer end of the function execution, but because of its variable object is still referenced scope of the inner function, memory and will not be recovered until the closure end of the execution, the variable object layer will be recovered function.
Characteristics closure package - access closure features variable outer function:
If the outer closure after the execution function, then it can only be obtained in the final state of all the outer function variables.
* Example 1:
function father(){
    was = array [];
    for (var i=0; i<10; i++) {
        array[i] = function(){
            return i;
        }
    }
    return array;
}
After executing father function will return an array containing a closure, each closure returns i.
Here's closure due to call the outer function already executed over, the outer function object variable i has become a value of 9, at this time no matter which perform array of closures, the results are returned 9.
However, if during the execution of the closure the outer closure function is executed immediately, the result is not the same, see Example 2.
* Example 2:
function father(){
    was = array [];
    for (var i=0; i<10; i++) {
        array[i] = (function(){
            return i;
        })();
    }
    return array;
}
At this time, closure of the implementation function is executed immediately when the outer layer, at that time, the value of i and closing function of the current value of i is the outer package, so the returned array is stored will be 0-9.
However, examples 1 stored in the array is obviously closures, and here storage array is the result of closures carried out, then the storage array if still want closure, we need a little renovation, see Example 3.
* Example 3:
function father(){
    was = array [];
    for (var i=0; i<10; i++) {
        array[i] = (function(){
            var i = CURIE;
            return function(){
                return curI;
            }
        })();
    }
    return array;
}
We let the closure executed immediately return a closure, and the value for i loop is assigned to a local variable to perform the function immediately, this time in the storage array will be closures, and each has the right closure value.
This point in the closure --window; memory problems closure - closure function memory for larger than normal
Because if there is a function of internal closures exist, then the end of the function execution will not release their variable objects only when the closure will be released after the execution, so the closure will take up more memory space to store outside variable layer functions fulfilled.
Thus, when you can avoid it, do not use closures.
Closures are involved in the DOM object memory leak may occur
We know, JavaScript by the ECMAScript, BOM, DOM composition, in some browsers they use different language, so they have different garbage collection mechanism.
ECMAScript object takes tag memory recovery sweep algorithm, and the DOM object of some browsers use reference counting algorithm to reclaim memory. The reference count has a fatal drawback - the object of a circular reference can not be recovered.
For example: if a DOM object attributes in a point A to another DOM object B, but B has property b point to the object A, then there is a circular reference these two objects, garbage collection can not recover them, which resulted in a memory leak.
The step back, as long as a DOM object there are two objects circular references, it will cause a memory leak, see the following example:
function func () {
    var dom = document.getElementById("xx");
    dom.onclick = function(){
        alert (dom.id);
    }
}
This code gets a DOM object, and let the onclick attribute of this object points to a JS function object; and this in turn points to a function object id attribute of the DOM object, which appeared in a circular reference. Due to a DOM object exists in both objects, and therefore there will be a memory leak.
How to avoid?
To resolve memory leaks, as long as we destroy two object references to each other.
The code to add a click event dom, therefore dom.onclick property must point to a JS function object, so this reference can not be cut off.
While the second reference is a function object pointed JS DOM objects, the purpose is to obtain the id dom, we can cut off this reference by the following code:
function func () {
    var dom = document.getElementById("xx");
    was _id = dom.id;
    dom.onclick = function(){
        alert(_id);
    }
}

Guess you like

Origin www.cnblogs.com/shidawang/p/11964470.html