Anonymous functions and closures

1. Assign anonymous functions to variables

var test = function() {
    return 'guoyu';
};
alert(test);//test is a function
alert(test());

2. Assigning the return value of the self-execution of anonymous functions to variables

var test = (function() {
    return 'GY';
})();
alert(test);//Pop-up GY

3. Self-execution. The first parentheses place anonymous functions, and the second parentheses execute and pass parameters.

(function(a, b) {
    alert(a+b);
})(2,5);//Direct ejection 7

4. Self-persistent Anonymous Functions

alert((function() {
    return 'guoyu';
})());

5. Put an anonymous function in the function.

function test() {
    return function() {
        return 'guoyu';
    };
}
alert(test());//Execute test(), and the result is a function body
alert(test()());//Pop-up guoyu

var t = test();
alert(t());//Pop-up guoyu

closure

Closure refers to a function that has access to variables in the scope of another function. A common way to create a closure is to create another function within a function and access local variables of the function through another function.

1. Local variables can be returned through closures

function test() {
    var age = 28;
    return function() {
        return age;
    };
}
alert(test()());//Direct pop-up 28

2. Closures have both advantages and disadvantages: Local variables reside in memory, avoiding the use of global variables (global variable pollution leads to unpredictability of the application, each module can be invoked will lead to disaster, recommending the use of private, encapsulated local variables)

Accumulate using global variables
var age = 20;
function test() {
    age++;
    return age;
}
alert(test());//21
alert(test());//22
 If you put var age = 20; into the test() function, then every execution will be reinitialized to 20, each pop-up is 21, no matter how many executions!

3. Accumulate local variables by using anonymous functions to reside in memory

function test() {
    var age = 20;
    return function() {
        age++;
        return age;
    }
}
var t = test();
alert(t());//21
alert(t());//22
alert(t());//23
alert(t());//24
/*If age = 20 is initialized every time, then every return is 21, and accumulation cannot be achieved, so to avoid initializing that sentence, just call the first return statement, and only call t() every time.*/
t = null;//Dereference, waiting for garbage collection

The Valuation of Anonymous Functions in Cycles

function test() {
    var arr = [];
    for (var i = 0; i < 5; i++) {
        arr[i] = function() {
            return i;
        };
    }

    //When the loop is finished, i ends up being4++,Namely5
    return arr;
}

/*
    alert(test());
    Print out5Parallel“function() {return i;}",
    Because each element of the arr ay is an anonymous function, each anonymous function returns"i",
    Not returning123....,Because the anonymous function is dead, no execution (self-execution)
*/
alert(test()[0]);//Ejection“function() {return i;}"

var t = test();

for (var i = 0; i < 5; i++) {
    //alert(t[i]); // Array is an anonymous function without self-execution


    //Now let each dead function in the array execute, but it all pops up.‘5'
    //Because after executing the loop in test(), i is already5Yeah, but there's a dead function in every array, which returns a dead function. i
    alert(t[i]());
}

How to solve the above problems?

Amendment 1

function test() {
    var arr = [];
    for (var i = 0; i < 5; i++) {
        arr[i] = i;//Instead of anonymous functions, give me an i.
    }
    return arr;
}

var t = test();

for (var i = 0; i < 5; i++) {
    alert(t[i]);//Pop-up in turn0,1,2,3,4
}

Modify 2 to execute anonymous functions instantly by self:

//Resisting variables in anonymous functions in memory feels like global variables
function test() {
    var arr = [];
    for (var i = 0; i < 5; i++) {
        arr[i] = (function(num) {
            return num;
        })(i);
    }
    return arr;
}

var t = test();

for (var i = 0; i < 5; i++) {
    alert(t[i]);//Pop up 0, 1, 2, 3, 4 in turn
}

Amend 3:

function test() {
    var arr = [];
    for (var i = 0; i < 5; i++) {
        arr[i] = (function(num) {
            //return num;
            return function() {//That's closure. Closure resides variables in memory, which adds up to the previous example.
                return num;
            };
        })(i);
    }
    return arr;
}

var t = test();

for (var i = 0; i < 5; i++) {
    //alert(t[i]); here five functions () {return num;} are returned.
    alert(t[i]());//Print out 0, 1, 2, 3, 4 in turn
}

this in closures

var test = {
    getThis: function() {
        return this;
    }
};

alert(test.getThis());//[object Object]

Look again at the closure:

var test = {
    getThis: function() {
        return function() {//That's closure.
            return this;
        };
    }
};

alert(test.getThis()());//[object Window]

CONCLUSION: This object is bound to the execution environment based on function at runtime. If this is widow in the global scope, it will point to this object if it is inside the object. Closures point to window s at run time because they do not belong to the properties or methods of this object. Look at the following

var user = 'The Window';
var box = {
    user:'The Box',
    getUser: function() {
        //return this.user;
        return function() {//That's closure.
            return this.user;
        };
    }
};

alert(box.getUser()());//The Window

So some students want to ask, how can it pop up The box?
There are two methods: object impersonation and variable preservation_this

var user = 'The Window';
var box = {
    user:'The Box',
    getUser: function() {//This place needs to be impersonated.
        return function() {
            return this.user;
        };
    }
};

alert(box.getUser().call(box));//The Box
var user = 'The Window';
var box = {
    user:'The Box',
    getUser: function() {
        var _this = this;//Save to temporary variables
        return function() {
            return _this.user;
        };
    }
};

alert(box.getUser()());//The Box

Imitating block-level scope, encapsulating things in block-level such as for and if, privatizing variables, can protect data and prevent leakage. js has no concept of private scope

function test() {
    for(var i = 0; i < 5; i++) {//Block scope, unfortunately JS does not have this thing

    }
    var i;//Re-declaration does not affect either.
    alert(i);//Even beyond the for block level, print out 5, indicating that js does not have the concept of block-level scope
}
test();

Start using block-level scopes, i.e., if, for blocks, etc., where I no longer works, by including self-executing anonymous functions, you can achieve private scopes.

function test() {
    (function() {
        for (var i = 0; i < 5; i++) {//Including self-executing anonymous functions enables private scopes
            alert(i);
        }
    })();

    alert(i);
    //i don't know here. It's equivalent to not defining i. i was destroyed. Continuing to define i has nothing to do with the above i to prevent pollution.
}
test();
(function() {
    var age = 20;
    alert(age);
})();
alert(age);//Error reporting, undefined
//In this way, global variables can be privatized to prevent pollution.

Private variables (external inaccessibility)

function test() {
    var age = 20; //private variable
}
function Test() {
    this.age = 20;//Attributes: Public, externally accessible
    this.run = function() {//Method: Public
        return 'is running...';
    };
}


var t = new Test();
alert(t.age);
alert(t.run());
function Test() {
    var age = 20;  //private variable
    function run() {//Private function
        return ' is running...';
    }

    this.publicGo = function() { //Externally visible public interfaces, privileged methods
        return age + run();
    };
}

var t = new Test();
alert(t.publicGo());
//20 is running... private variables, private functions, accessed through public interfaces
//Encapsulate some details and access them through some interfaces

Added by popsiclesph on Fri, 28 Jun 2019 22:37:12 +0300