js function closure to understand! Look at these two questions? Measure the level!

Posted by john87423 on Wed, 07 Aug 2019 15:20:14 +0200

Introduce closures you understand? Anyway? I've heard it many times lately! It feels like I can't face those sharp questioning without a good summary!
If you think closures are well understood, just skip to the end!

1. Closure concept

Xiao Hongshu's interpretative closure is a function that has access to variables in the scope of another function. See? It's a function, a function that can access variables in other functions. So the common way to create closures is to create another function within one function.

function bag(num){
    return function(){
        return num
    }
}
var bagc = bag(12)
console.log(bagc()) //12

You can see that the anonymous function inside the bag can access the variable num of the external bag function.

2. Use of closures

Closures can be used in many places. Its greatest use is two, one is to read the variables inside the function, and the other is to keep the values of these variables in memory all the time.

function f1(){

     var n=999;

     nAdd=function(){n+=1}

    function f2(){
      alert(n);
    }

    return f2;

}

var result=f1();

result(); // 999 

nAdd(); //Variable n is saved

result(); // 1000

The above is an example of Ruan Yifeng in the document. I think it's very useful to read the internal variables of the function. It's quite useful to keep the variables in memory, such as that=this, which is often used. Let's look at a common question:

 for(var i = 0;i <10;i++){
     setTimeout(()=>{
        console.log(i)
     },1000)
  }
  //The above code we want to print according to the index value, but the result is printed 10 10, why not explain, i is a global variable.
  //The problem can be solved by replacing the following with the closure, which keeps the value of the variable in memory all the time. Every i exists in the local variable num.    
        
  for(var i = 0;i <10;i++){
      (function(num){
         setTimeout(()=>{
            console.log(num)
         },1000)
       })(i)
   }

3. Points for Attention in Using Closures

Although closures are good for solving some problems, we should pay attention to some problems arising from them. Because closures carry the scope of external functions, they occupy a large amount of memory, so we should use closures as little as possible and cautiously.

1. Variable problem

Because closures can use external variables, the use of variable i in the returned anonymous function will be the final value, and the return value of the stored function in the array will be 10.

function test() {
   var result = [];
   for(var i = 0; i<10; i++){
      result.[i] = function () {
         return i;
      }
   }
   return result
}

The above code needs to be rewritten as follows:

function test() {
   var result = [];
   for(var i = 0; i<10; i++){
      result.[i] = function (num) {
         return function() {
           console.info(num);  
         }
      }(i)
   }
   return result
}

The num accessed at this time is the num of the upper function execution environment. There are 10 function objects in the array. Numbers in the execution environment of each object are different.

2.this problem

The execution of anonymous function is global, so this of closure function generally points to window.

var object = {
     name: "object",
     getName:function() {
        return function() {
             console.info(this.name)
        }
    }
}
object.getName()()    // underfined
// Because the closure function inside is executed in windows scope, that is, this points to window s.

It can be rewritten as follows:

var object = {
     name: "object",
     getName:function() {
        var that = this;
        return function() {
             console.info(that.name)
        }
    }
}
object.getName()()    // object

3. Memory leak

If a closure holds an html element in the scope chain, the memory of that element cannot be automatically destroyed.

function  showId() {
    var el = document.getElementById("app")
    el.onclick = function(){
      aler(el.id)   // This causes the closure to refer to the outer el, which cannot be released after showId is executed
    }
}

// Change to the following
function  showId() {
    var el = document.getElementById("app")
    var id  = el.id
    el.onclick = function(){
      aler(id)   // This causes the closure to refer to the outer el, which cannot be released after showId is executed
    }
    el = null    // Active release of el
}

4. Closure exercises

Okay, do you feel that you have a good understanding of closures here? Don't worry, take a look at these two little questions and test them!

1. Combining with function calls

var Test = {
    close:function(val){
        return function (z){
            return ++ val +z
        }
    }
}
var getClose = function(val){
    return Test[val]
}                         
var fn = getClose('close')
var cover = fn(100)
console.log(cover(200)) 
console.log(cover(300))
console.log(fn(100)(200))
console.log(fn(100)(200))
console.log(getClose('close')(100)(300))

//The output is at the end.

2. Combining with dom

var container1 = document.getElementById('container1')
var container2 = document.getElementById('container2')
var container3 = document.getElementById('container3')
var container4 = document.getElementById('container4')
var container5 = document.getElementById('container5')

var innerHTML = 'window Of html'
var events = {
    innerHTML:'I am events',
    getHtml:function (){
        console.log(this.innerHTML)
    },
    setFun:function(){
        return this.getHtml
    },
    proxy:function(){
        var self = this;
        return function(){
            self.getHtml()
        }
    }
}
container1.onclick = events.getHtml; 
container2.onclick = events.setFun();
container3.onclick = events.proxy();
container4.onclick = function(){
    window.setTimeout(events.setFun(),0)
}
container5.onclick = function(){
    window.setTimeout(events.proxy(),0)
}

ok? Have you ever been stunned? Turn on the computer and knock if you feel dizzy.

Take a look at the output.
Topic 1: 401 402 301 301 401
 Second question: container container container 2 I am the html of events window I am events









Topics: Javascript Windows