javascript closure detail

  • 2020-06-22 23:51:47
  • OfStack

Take a look at the concepts and articles about closures on the Web and do your own review of the problem.

Q: What is a closure?
A: Closures mean that in JavaScript, an inner function can always access the arguments and variables declared in the outer function in which it is located, even after its outer function has been returned (end of life).

This is the first time I've encountered a closure myself


<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8"/>
<title> Closure loop problem </title>
<style type="text/css">
p {background:#ccc; width: 300px; height: 100px;}
</style>
</head> 
<body> 
<p id="p0"> The paragraph 0</p> 
<p id="p1"> The paragraph 1</p> 
<p id="p2"> The paragraph 2</p> 
<p id="p3"> The paragraph 3</p> 
<p id="p4"> The paragraph 4</p> 
<script type="text/javascript">
for( var i=0; i<5; i++ ) { 
document.getElementById("p"+i).onclick=function() { 
alert(i); // The variable of the parent function is accessed i,  closure  
};
};
</script> 
</body> 
</html>

If you haven't used it before, you might think that clicking on a paragraph will bring up the corresponding number 0,1,2,3,4. But it's always pop 5;

There have been a lot of blogs on the web on this issue, and they've given a number of ways to implement pop-up Numbers.

Solution 1: Save the variable i on an attribute in the corresponding paragraph


var pAry = document.getElementsByTagName("p"); 
for( var i=0; i< 5; i++ ) { 
pAry[i].no = i; 
pAry[i].onclick = function() { 
alert(this.no); 
} 
};

Solution 2: Add a layer closure, and i is passed to the inner function as a function argument


var pAry = document.getElementsByTagName("p"); 
for( var i=0; i< 5; i++ ) { 
pAry[i].no = i; 
pAry[i].onclick = function() { 
alert(this.no); 
} 
};

For this resulting closure problem, the web says that "the variable i is stored in a function as a pointer or variable address"; Well, it's all about the pointer... So let's explore 1 more.

Explore 1, return 10 instead of 10


(function test() { 
var temp =10; 
for(var i=0; i< 5; i++ ){ 
document.getElementById("p"+i).onclick=function() { 
alert(temp); // The variable of the parent function is accessed temp,  closure  
}
};
temp=20;
})();

Explore 2, return 10 once, return 20 the next time


(function test() { 
var temp =10; 
for( var i=0; i< 5; i++ ) { 
document.getElementById("p"+i).onclick=function() { 
alert(temp); // The variable of the parent function is accessed i,  closure  
}
if(i===1){
alert(temp);
}
};
temp=20;
})();

From the exploration of 1 and 2, it can be concluded that the function internally accesses a variable of the same level as the function, then the variable is resident in memory. Accessing the variable is essentially accessing the address of the variable;

Then, after reading another article about this objects in JS closures, let's move on to this.


// js closure this object 1
var name = 'The Window';
var object = {
  name : 'My Object',
  getNameFunc1 : function(){
    // return this.name;
    console.log(this);//object
    return function(){// A closure that accesses a global variable, this Refers to the windows
     console.log(this);//windows
     return this.name; //The Window
    }
  },
  getNameFunc2 : function(){
     return this.name;// Access is object
  },
  aa:function(){
   alert(22);
  }
};
alert(object.getNameFunc1()());// The pop-up" The Window " 

Q: So why doesn't the anonymous function get the this object with its scope?
Answer: Each function automatically gets two special variables when it is called: this and arguments. When an internal function searches for these two variables, the conductor searches until it reaches its living object, so it is never possible to directly access these two variables in an external function.
But you can do this (directly accessing variables in external functions) with the following code:


// js closure this object 2
var name = 'The Window';
var object = {
  name : 'My Object',
  getNameFunc : function(){
   var that = this;
   console.log(this);// The output is object
   return function(){
    console.log(this);// The output is still the same Windows
    return that.name;
   };
  }
};
alert(object.getNameFunc()());// The pop-up" My Object " 

The difference is that the this object is assigned to an that variable, and that still references the object even after the function returns, so it returns object.
I've written a lot about closures, so let's talk a little bit about what they're good for; Otherwise, the closure is really a bad guy.

Look at this 1 example of a typical closure:


function A(){
 var a=1;
 function B(){
  return a;
 }; 
 return B;
};

var C=A();//C achieve A The subscope of B Access interface 
console.log(C());//1 C Access to the B Variables in the parent scope of a 

As long as other scopes have access to the access interface of the child scope, then other scopes have methods to access variables of the parent scope of that child scope. This will be useful if you need to access the value of a function in the future.

These above a lot of code is actually found on the Internet, I also just put their own understanding, look at the process of summary 1.


Related articles: