What is JavaScript closure

JS closure

MDN defines a closure as a function and a reference to its state, the lexical environment. That is, closures allow you to access external function scopes from internal functions. In JavaScript, functions generate closures each time they are created.
In general, when a function accesses a variable in another function's local scope, it generates a closure
Action: extend the action range of the variable so that the local variable stays in the memory and is not destroyed
Disadvantages: variables are not destroyed and memory leaks occur

Let's first look at the local scope and garbage collection mechanism through a wrong example

    function func() {
        var num = 10;
	console.log(num);	
    }
    func();//Output 10
    console.log(num);//num is not defined

Conclusion: the variables defined by the internal scope of a function, i.e. the local scope of a function, cannot be accessed outside a function. In the function, after the func function, 1. Define the variable, 2. Output by console.log, 3. Exit the function variable I after being called, lose the reference and be garbage collected.
In javascript, if an object is no longer referenced, it will be recycled by the garbage collection mechanism;

Let's look at a simple closure case

   // A closure occurs when a function accesses a variable in another function's local scope
    function fn() {
        var str = "This is a character!";
        return function () {
            return str;
        }
    }
    let f =fn();
    console.log(f());//The output string accesses the variable str in the local scope of the fn function outside fn to generate a closure
    // f = "this is a character! ";
    // The fn() function is called a closure function

Conclusion: the method which is regarded as the return value accesses the str variable in the local scope of fn(), and generates the closure. At the same time, we receive the return value through the variable F function outside fn(), f = str, and successfully accesses the srt variable in the local scope of the function; the srt variable in phase change also extends its value to the global;

Two cases to understand the function of closure

Define an array and print its contents in three seconds
var arr = [11,22,33];

//1. Conventional methods
   for (var i = 0;i<arr.length;i++){
        setTimeout(()=>{
            console.log(arr[i]);//Printout
        },3000)
   }
//

Result: Error Report
undefined*3
Reason: the for loop is a synchronous function, while the timeout callback function is an asynchronous function. After the execution of the for loop, the variable i has been reassigned by the subsequent i + + operation of the for loop, and the current value is 3, resulting in an error.
Solution: reference the value of variable i generated by each for loop through closures to generate a reference relationship to keep the variable alive, but i=0,i=1,i=2 are added in memory; four values generate a memory overflow.

//2. Closure
   for (var i = 0;i<arr.length;i++){
	//Generate 4 immediate functions through for loop and pass in i value to generate reference relationship
        (function (i) {
            setTimeout(()=>{
                console.log(arr[i]);//Printout
            },3000)
        })(i)
	//Callback method in Timeout accesses variable i in immediate function to generate closure
    }

Result:
[0,1,2,3]
Normal output, closure generated by the usage range of extension variable i

Let's take a look at a classic case

Click three buttons to get its index value

<ul>
    <li>
        <button>Button 1</button>
    </li>
    <li>
        <button>Button 2</button>
    </li>
    <li>
        <button>Button 3</button>
    </li>
</ul>
<script>

//1. Get element
var lis = document.querySelectorAll("button");

//2. Solve the problem that for loop is a synchronization method by dynamically adding attributes
    // for(var i = 0;i<lis.length;i++){
    //     lis[i].index = i; / / add attributes dynamically
    //     lis[i].onclick = function () {
    //         console.log(i);
    //         console.log(this.index); / / output dynamically added attribute values by calling the object of onclik method
    //     }
    // }


//3. Through closure
for(var i = 0;i<lis.length;i++){
        //Using for loop to create four immediate execution functions
        (function (i) {
	    //Pass the value of the current i variable to the immediate execution function to generate a reference relationship to generate a closure. The immediate execution function is a closure function
            lis[i].onclick = function () {
               console.log(i);
           }
        })(i)
    }

</script>

Execute function now

js immediate execution function enables your function to execute immediately after creation, and enables your function to be executed immediately after definition. This mode is essentially function expression (named or anonymous), which is executed immediately after creation. It is a synchronization function that will be put into the macro thread.

Common way

   //1. brackets
    (function (Pass value) {
        
    })(Pass value)


   //2. Add special sign + - x ~! Void NEW
    !function (str) {
      console.log(str)
    }("This is the character!")

Effect:
1. Create a separate scope.
2. Avoid pollution of other global variables.
3. Variables outside the scope can be referenced by parameter values

Published 8 original articles, won praise 0, visited 32
Private letter follow

Tags: Javascript Attribute

Posted on Mon, 13 Jan 2020 05:12:18 -0500 by jamie85