A brief introduction to closures in javascript

  • 2020-06-12 08:26:20
  • OfStack

It took a long time to understand closures, but then to understand the scope and this issues.
Closures, or closure, are also frequent interviewees. In simple terms, functions are nested functions.

Function as the return value:


function foo () {
  var a = 1;
  return function () {
   a++;
   console.log(a);
  }
}
var aaa = foo();
aaa(); //2
aaa(); //3

aaa refers to a new function returned by foo(), but it refers to the a variable, so when the foo function is finished, the variable a is still in memory. a is 2 and 3, respectively.

Function as a parameter:


var a = 10;
function foo () {
console.log(a);
}
function aaa(fn) {
 var a = 100;
 fn();
}
aaa(foo);

According to my previous understanding, when executing the fn function inside the aaa function, if you don't have the a variable by itself, go to the parent scope and find the a variable, which is 100 here, will the result be 100?

Unfortunately, the answer is not, in this case it's 10, and Wang Fupeng, who has a better blog, says to create the scope of this function, not the "parent scope."

Usage scenarios for closures

Because I am still relatively new, here to take a simple example. When you click on li, the position of li in ul pops up as the index value.

html code:


<ul>
  <li>001</li>
  <li>002</li>
  <li>003</li>
</ul>

js code:

Example 1:
Look at the code below. After running it, no matter which li you click on, the result is 3.


var aLi = document.getElementsByTagName('li');
for (var i = 0; i<aLi.length; i++) {
  aLi[i].onclick = function() {
   alert(i);
  }
}

Since there is no i variable in the anonymous function, when for is finished, we click on the li TAB of the page and i is already 3.

Example 2:


aLi[i].onclick = (function(i){
    return function(){
      alert(i);
    }
  })(i);

The method is to pass in the i variable as the return value, using the arguments of the self-executing function, and since the return function refers to the i variable, the i variable will not be released when the for loop ends. That is, the value of the i variable is stored in memory. Based on this principle, it is easy to cause memory leaks in the lower versions of ie.

Example 3:


for (var i = 0; i<aLi.length; i++) {
  (function(i){
    aLi[i].onclick = function(){
      alert(i);
    }
  })(i);
}

The principle is much the same as above.

Xiaomi Front-end closure interview Question:


function repeat (func, times, wait) {
} // This function returns 1 A new function, let's do it this way 

var repeatedFun = repeat(alert, 10, 5000)
// Call this  repeatedFun ("hellworld")

// will alert10 time  helloworld,  Each time interval 5 seconds 

My answer:


function repeat (func, times, wait) {
  return function(str) {
    while (times >0) {
      setTimeout(function(){
        func(str);
      },wait);
      times--;
    }
  }
}

var repeatedFun = repeat(alert, 10, 100);
repeatedFun ("hellworld");

That's it for this article, and I hope it helps you learn about javascript closures.


Related articles: