This is the 10th day of my participation in Gwen Challenge

Closures, some say it’s a design concept, some say all functions are closures. I don’t know how to define it, and I’m not going to define it, but to define it is to limit the understanding of it. The key to understanding closures is that the variable object of an external function is supposed to be destroyed after the call, but the existence of the closure allows us to access the variable object of the external function.

function outer() {
    var a = 1;
    return function() {
        return a;
    };
}
var b = outer();
console.log(b()); / / 1
Copy the code

Module-level scope

(function(){
    var now = new Date(a);if (now.getMonth() == 0 && now.getDate() == 1) {
        alert('Happy new Year! ');
    }
})();
Copy the code

This approach is often used to limit the number of variables and functions added to the global scope.

Creating private variables

(funcion() {
    var a = 1;
    setA = function(val){
        a = val;
    };
    getA = function(){
        returna; }; }) ();console.log(a); / / an error
console.log(getA()); / / 1
setA(2);
console.log(getA()); / / 2

// You can also write:
function outer(){
    var a = 1;
    return {
        setA: function(val) {
            a = val;  
        },
        getA: function() {
            returna; }}; }var closure = outer();
console.log(a); / / an error
console.log(closure.getA()); / / 1
closure.setA(2);
console.log(closure.getA()); / / 2
Copy the code

In the first example, both setA and getA are global variables used to read and write private variable A. The second example returns the two methods as one object and assigns them to a global variable closure, so that when outer completes, the two methods (anonymous functions), along with the variable object (a) in the outer function, will not be destroyed.

Closures are used to create instance objects with private variables, see Using closures to create instance objects with private attributes

Closures can only get the last value of any variable in the function

function arrFunc() {
    var arr = [];
    for (var i=0; i<10; i++) {
        arr[i] = function() {
            return i;
        };
    }
    return arr;
}
Copy the code

The arR array contains 10 anonymous functions, each of which has access to the variable I of the external function. What is I? When arrFunc completes execution, its scope is destroyed, but its variable object remains in memory and can be accessed anonymously, at which point I has a value of 10. To store the value of each I in the loop, an anonymous function is applied to the anonymous function, in which another variable is defined and executed immediately to hold the value of I.

function arrFunc() {
    var arr = [];
    for (var i=0; i<10; i++) {
        arr[i] = function(num) {
            return function() {
                return num;
            };
        }(i);
    }
    return arr;
}
console.log(arrFunc()[1] ());/ / 1
Copy the code

In this case, the innermost anonymous function accesses the value of num, so the 10 anonymous functions in the array return values of 1-10.

This in the closure

var name = 'window';
var obj = {
    name: 'object'.getName: function() {
        return function() {
            return this.name; }; }};console.log(obj.getName()()); //window
Copy the code

Obj.getname ()() actually calls an anonymous function in the global scope; this refers to the window. It is important to understand that the function name is separated from the function function. Do not assume that the this inside the function refers to where the function is. Windows is the environment in which anonymous functions are performed. To make this refer to the execution environment of an external function, rewrite this as follows:

var name = 'window';
var obj = {
    name: 'object'.getName: function() {
        var that = this;
        return function() {
            returnthat.name; }; }};console.log(obj.getName()()); //object
Copy the code

Arguments have the same problem as this. Also note the following:

var name = 'window';
var obj = {
    name: 'object'.getName: function() {
        return this.name; }}; obj.getName();//object
(obj.getName = obj.getName)(); //window in non-strict mode
Copy the code

obj.getName(); GetName () is executed in the context of the object obj, so this points to obj. (obj.getName = obj.getName); (obj.getName = obj.getName); (obj.getName = obj.getName); This points to the global. Separate function names from function functions.

A memory leak

Closures refer to the entire variable object that contains the function, and if the closure holds an HTML element in its scope chain, that means that element cannot be destroyed. Therefore, it is necessary to destroy the element actively after the operation.

function assignHandler() {
    var element = document.getElementById('someElement');
    var id = element.id;
    element.onclick = function() {
        alert(id);
    };
    element = null;
}
Copy the code

The timer inside the function

When a timer inside a function references a variable object of an external function, the variable object is not destroyed.

(function() {
    var a = 0;
    setInterval(function(){
        console.log(a++);
    }, 1000); }) ();Copy the code

The key to using closures

  1. Closures refer to values in external function variable objects;

  2. Call closure outside of an external function.