What is a closure

Closures are functions that refer to variables in the scope of another function, usually implemented in nested functions. Whenever a function refers to an external variable, this phenomenon is called closure

1. Characteristics of closures

Disadvantages: When the external function ends, the internal function still exists and occupies the variables of the external function. As a result, the external function cannot release the memory, resulting in memory leakage. Advantages :1. The variable is defined inside the function (external function) belongs to the local variable, will not be external pollution 2. Internal functions have access to the arguments and variables of the external functions that define them (except this and arguments)

2. Fix closures

Actively free memory used by closures when internal functions are no longer in use (see demo).

3.demo

The inner function is an anonymous function nested in the outer function setElement, which refers to the index and arr variables of the outer function. When the inner function is returned and used elsewhere, it still uses these two variables, and even after the outer function has finished calling, it still does not free memory. The function created here is stored in the variable getElement. Setting getElement to NULL touches the reference to the function, which is released by the garbage collection system, and the scope is destroyed.

<body>
    <button>Since the increase</button>
    <h1></h1>
    <script>
        const btn = document.querySelector('button');
        const h1 = document.querySelector('h1');

        // Closure features: When the outer function ends, the inner function still exists and occupies the variables of the outer function
        // External functions cannot free memory.

        function setElement() {
            1. Define an array
            let arr = [
                { name: "Gold" },
                { name: "Wood" },
                { name: "Water" },
                { name: "Fire" },
                { name: "Soil"}];// 2. Define an index
            let index = -1;         // Is not a valid subscript for the array

            // 3. Return a function
            return function () {
                // 3.1 Modifying index
                index++;            // The current function has no index. It accesses an external index

                / / 3.2
                if (index > arr.length - 1) {
                    index = 0;     // display the subscript 0," gold"
                }

                // 3.3 Returns the current data
                return arr[index].name;
            };
        }

        // Call setElement
        let getElement = setElement();

        SetElement () has finished executing
        // setElement memory should be released (index, arR)
        // However: the current function cannot be executed because it returns a function that uses index and arr
        // Free memory (memory is always occupied) : closure
        // console.log(getElement);

        h1.innerText = getElement();/ / rendering

        // Click the event
        // Click call function, subscript ++ to display different data
        btn.onclick = function () {
            h1.innerText = getElement();
        };


        // Assume there is a lot of code to run: the above memory will always be used (although the code is safe and there is no contamination)
        // Solve the problem of closures: actively release the memory occupied by closures


        // Free the memory to comment on the following line of code
        // getElement = null;          
        // getElement no longer refers to the closure function, and the closure function does not need to use variables arr and index: setElement

    </script>
</body>
Copy the code

4. This object

Using this in closures can be complicated

  • If the internal functionArrow functions are not usedDefinition,thisThe context in which the function is executed is bound at run time.
  • If called from a global function, this equals window in non-strict mode and terminates with undefined in strict mode
  • If called as an object method, this refers to that object
window.identity = 'this is the window'
        let obj = {
            identity: 'this is the obj.getIdentity() {
                // Return the inner function
                return function () {
                    return this.identity
                }
            }
        }
        console.log(obj.getIdentity()());/ / this is the window
        // Note that there is also ()
Copy the code

This does not refer to the current scope because arguments and this cannot be accessed directly from internal functions. Arguments can be stored in variables that can be accessed from inside the package. Let that = this

 <script>
        window.identity = 'this is the window'
        let obj = {
            identity: 'this is the obj.getIdentity() {
                let that = this
                // Return the inner function
                return function () {
                    return that.identity
                }
            }
        }
        console.log(obj.getIdentity()());/ / this is obj
        // Note that there is also ()
    </script>
Copy the code