JS closures can only be eaten for as long as a thousand layers of mango

When learning js, you will more or less learn about closures, because it is a bit strange, so it is obscure. Here are some concepts of closure creation.

 Closures can create an independent environment. The environment in each closure is independent and does not interfere with each other. A memory leak will occur in the closure. Each time the external function is executed, the reference address of the external function is different, and a new address will be recreated .

( Source article above- https : //blog.csdn.net/weixin_43586120/article/details/89456183 , very good article, I recommend you to take a look. Some of the code examples below also refer to this article, if The author is offensive, I will delete this article )

       Then, if we carefully read this paragraph (10 times in silence, please slow down in red), you will find that a new address will be created when the externally referenced address is different. The variables in it will not be refreshed. When the new address is referenced , the variables in the closure will be refreshed . Based on this passage we come to "Kang Kang" a few examples we will understand.

Example 1.

function fun1(){
    var num = 0;
    function fun2(){
      num ++;
      console.log(num)
    }
    return fun2
}
var a = fun1();
var b = fun1();
a();
b();
a();
b(); 
//输出为 1 1 2 2

Look at the clam, using the sentence above to understand, is a a new address? Yes. Is b a new address? Yes. Therefore, a and b do not affect each other. So how many a () is called before b () will not affect b's own variable. Which, I call it as follows?

fun1()()
fun1()()
//输出为 1 1 

The same, the two referenced addresses are different, so they do not affect each other. (Additionally, some readers may not understand why there are two brackets. That is because the first bracket is to call the method of fun1 , and then fun1 returns the method of fun2 , so the meaning of the second bracket is to call the method of fun2 in fun1 .) This supplement we introduce the next example.

Example 2.

var fun1 = function(x) { 
    var sum = 1; 
    var fun2 = function(x) { 
        sum = sum + x; 
        return fun2;    
    } 
    fun2.toString = function() { 
        return sum; 
    }
    return fun2; 
} 
console.log(fun1(1)(2)(3));  
//输出为 6 

Some readers may be ashamed when they come up. what is this? But we are professionally trained people and we will not be afraid unless we are really scary. But this is not difficult to understand, the interpretation of the three brackets can refer to a paragraph to add. Take a closer look at these codes. The first parenthesis, fun1 (1), will generate a new address after the method is executed, execute sum = 1, and return the fun2 function. The second parenthesis is to call the returned fun2 function. The fun2 function can receive one parameter and add it to sum. Because the memory has not changed, at this time, sum is the 1 executed by the first parenthesis, not the incoming 1 so you execute the following code:

console.log(fun1()(2)(3));  
//输出为 6 
console.log(fun1(800000)(2)(3));  
//输出为 6 

It's the same. Some students may also wonder: "Which parameter x?" Actually, this x, because fun2 is not called in fun1, but the toString method of fun2 is called, so these two x have no effect unless called in fun1 Fun2. After the execution of fun2 (2) above, the value of sum becomes 1 + 2 which is 3, the same, the third bracket becomes 3 + 3, so the result is 6, of course, you can always set Baby go on. Looking back at the entire process, the address where the closure was created has not changed, so the value of sum has not been refreshed. Based on this, let's make a revision and call fun1 in fun2, see example 3 below.

Example 3.

function fun1(num1, num2) {
      console.log(num2);
      return {
           fun2:function(num3) {
                 return fun1(num3, num1);
           }
      };
}
var a = fun1(0);  //undefined
a.fun2(1);        //0  
a.fun2(2);        //0  
a.fun2(3);        //0  
var b = fun1(0).fun2(1).fun2(2).fun2(3);
//undefined  0  1  2

Maybe you looked dumbfounded again, why is it a matryoshka again. In fact, Ollie Giao is finished (the other code is the same name of fun2 and fun1, that is disgusting, so I specifically separated the two names here for easy understanding. In fact, the same name is the same).

Look here, a is a new address, b is also a new address, these two do not affect each other. No matter how a operates, it cannot affect b. After confirming this, let's look at the code again. According to the interpretation of the previous paragraph, everyone who has read the above already understands seven or eight. Why the first one is undefined, because no parameters are passed, why a.fun2 (1) ... etc. are all 0, you can understand the execution of fun2, num1 = 0, already in var a = fun1 (0); It has been determined that a no matter how a2 calls fun2 later, it will not affect num1 = 1 from fun1. And a.fun2 (x) then look at the set of dolls in b. The same, it is easy to understand when brought in; 

 

Finally, to sum up, to see whether the variables of the closure have changed, I personally think it depends on whether the address of the closure has changed. Please indicate if there are errors, thank you very much.

Published 3 original articles · Liked5 · Visitors1072

Guess you like

Origin blog.csdn.net/weixin_39394140/article/details/105551971