Use Scenarios of JavaScript Closures

  • 2021-08-21 19:38:01
  • OfStack

1. Closures

Because in Javascript, only sub-functions inside a function can read local variables, closures are functions that can read variables inside other functions. Therefore, in essence, a closure is a bridge connecting the inside and outside of a function.

For example, the following code:


function f1() {
 var n = 999;
 function f2() {
 console.log(n);
 }
 return f2;
}
var result = f1();
result();//999

The function f2 is included inside the function f1, and all the local variables inside f1 are visible to f2. But the reverse is not true. Local variables inside f2 are invisible to f1.

This is the unique "chain scope" structure of Javascript language (chain scope), and the child object will look up all the variables of the parent object level by level. Therefore, all variables of the parent object are visible to the child object, otherwise it is not true.

Since f2 can read local variables in f1, you can read its internal variables outside f1 by taking f2 as the return value.

2. Use scenarios for closures

1.setTimeout

The first function passed by native setTimeout cannot take parameters, and the effect of passing parameters can be realized by closure.


function f1(a) {
 function f2() {
  console.log(a);
 }
 return f2;
}
var fun = f1(1);
setTimeout(fun,1000);//1 Print out after seconds 1

Step 2 Callback

Define the behavior and then associate it with a user event (click or key). Code is usually bound to the event as a callback (the function called when the event is triggered).

For example, the following code:


<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title> Test </title>
</head>
<body>
 <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="size-12">12</a>
 <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="size-20">20</a>
 <a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" id="size-30">30</a>

 <script type="text/javascript">
  function changeSize(size){
   return function(){
    document.body.style.fontSize = size + 'px';
   };
  }

  var size12 = changeSize(12);
  var size14 = changeSize(20);
  var size16 = changeSize(30);

  document.getElementById('size-12').onclick = size12;
  document.getElementById('size-20').onclick = size14;
  document.getElementById('size-30').onclick = size16;

 </script>
</body>
</html>

When you click on a number, the font will also change to the corresponding size.

3. Function anti-shake

The callback is executed after the event is triggered n seconds, and if it is triggered again within this n second, the time is re-timed.

The key to the implementation lies in the function setTimeOut. Because one variable is needed to save the timing, considering maintaining global purity, it can be realized by means of closure.

As shown in the following code:


/*
* fn [function]  Functions that require anti-shake 
* delay [number]  Milliseconds, anti-shake period value 
*/
function debounce(fn,delay){
 let timer = null // With closure 
 return function() {
  if(timer){
   clearTimeout(timer) // Enter the branch statement, indicating that the current 1 During the timing process, and the same event is triggered again. So you want to cancel the current timing and start the timing again 
   timer = setTimeOut(fn,delay) 
  }else{
   timer = setTimeOut(fn,delay) //  Entering this branch means that there is no timing at present, so start 1 Timing 
  }
 }
}

4. Encapsulate private variables

Like this: Create a counter with js

Method 1:


function f1() {
 var sum = 0;
 var obj = {
  inc:function () {
   sum++;
   return sum;
  }
};
 return obj;
}
let result = f1();
console.log(result.inc());//1
console.log(result.inc());//2
console.log(result.inc());//3

In the returned object, a closure is implemented, which carries the local variable x, and the variable x cannot be accessed from external code at all.

Method 2:


function f1() {
 var sum = 0;
 function f2() {
  sum++;
  return f2;
 }
 f2.valueOf = function () {
  return sum;
 };
 f2.toString = function () {
  return sum+'';
 };
 return f2;
}
// Execute function f1 Returns the function f2
console.log(+f1());//0
console.log(+f1()())//1
console.log(+f1()()())//2

All js data types have valueOf and toString methods except null
valueOf () method: Returns the original value of the specified object.
toString () method: Returns a string representation of the object.
In numeric operation, valueOf is invoked preferentially, and in string operation, toString is invoked preferentially
sum + ''is data of type 1 string

The above is the JavaScript closure usage scenario details, more information about JavaScript closure please pay attention to other related articles on this site!


Related articles: