What is a closure?

A closure is a nested function that caches the nested function and its execution environment until it is called again. Intuitively speaking is to form an undestroyed stack environment. This protects variables and methods and allows them to be privatized.


1. Privatization variables
function makeFunc() {
    var name = "Mozilla";
    function displayName() {
        alert(name);
    }
    return displayName;
}
// The closure hides the variable name and myFunc is not directly accessible
var myFunc = makeFunc();

// Name can only be accessed by executing a closure
myFunc();
Copy the code
2. Cache execution environment
function makeAdder(x) {
    return function (y) {
        return x + y;
    };
}

// The execution environment of the closure is cached, i.e. the value of x and nested functions are cached in add5
var add5 = makeAdder(5);

// call the execution closure, output: 7
console.log(add5(2));
Copy the code

3. Data encapsulation and hiding

There is no Java private keyword in JavaScript, but it can be implemented with closures to hide and encapsulate data.

// Successfully hide variables (privateCounter) and methods (changeBy)
var makeCounter = function () {
    var privateCounter = 0;
    function changeBy(val) {
        privateCounter += val;
    }
    return {
        increment: function () {
            changeBy(1);
        },
        decrement: function () {
            changeBy(-1);
        },
        value: function () {
            returnprivateCounter; }}};var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */
Copy the code

4. Performance optimization

It is not wise to create functions within functions unless there is a special need, because closures consume more CPU and memory resources and have a negative impact on script performance. When creating new objects, you should define methods in Prototype, not object constructors. Because every time you create an object, you reassign the method in the constructor.

// A bad way to use closures,
// Because every time new MyObject, getName and getMessage are reassigned
function MyObject(name, message) {
    this.name = name.toString();
    this.message = message.toString();
    this.getName = function () {
        return this.name;
    };

    this.getMessage = function () {
        return this.message;
    };
}
Copy the code
// Use this method instead of the above.
// Prototype is shared by all MyObject objects without reassigning getName and getMessage
function MyObject(name, message) {
    this.name = name.toString();
    this.message = message.toString();
}
MyObject.prototype.getName = function () {
    return this.name;
};
MyObject.prototype.getMessage = function () {
    return this.message;
};
Copy the code

Ii. Reference Documents:
  • What is a JavaScript closure?