closure

This is the third day of my participation in the August More text Challenge. For details, see:August is more challenging

preface

I first heard about closure when I was a senior student at an interview. At that time, I listened to some seniors’ explanation (although I didn’t understand it), but I felt that it seemed very advanced.

Now, after a year of working with closures, I can finally talk about my understanding of them.

What is a closure?

What is a closure? Functions that have access to variables in the scope of another function are closures.

Here’s an example:

function drink() {
	var beerName = "Snow Beer";
	let beerNum1 = 1;
	const beerNum2 = 2;
	var innerBeer = {
		getBeer:function() {
			console.log(beerNum1)
			return beerName
		},
		setBeer:function(newBeer) {
			beerName = newBeer
		}
	}
	return innerBeer
}
var go = drink();
go.setbeer("Smother the donkey.");
go.getBeer();
console.log(go.getBeer())
Copy the code

When we use getBeer and setBeer, they have no variables inside beerNum1 and beerName, so what do they do, those of you who have studied the scope chain know, they look outside, they look inside the drink function, I found it, so it’s ready to use.

Drink is a function, and its scope is called function scope. After drink is executed, that scope is destroyed, so what does innerBeer do?

Again, because of the scope chain, when innerBeer calls its two methods again, even after drink has been executed, the variables it uses cannot be destroyed. In other words, beerNum1 and beerName are forced to become holdouts.

InnerBeer: As long as I’m using, you can’t destroy it!

And this is the closure.

✌. This is my waterways

Why are closures prone to memory leaks?

First we need to know a concept: what is a memory leak?

When a variable is created in memory that cannot be reclaimed, it is called a memory leak

Var go = drink();

Go is a global variable that can be called setBeer and getBeer at any time, since we assigned the return value of the function to it and it will persist as long as the page is not destroyed. BeerNum1 and beerName are used for setBeer and getBeer, which is the nail house theory mentioned in the previous article. Combined with JavaScript’s garbage collection mechanism, we now know that these two holdouts are impossible to clean up.

This memory contains beerNum1 and beerName, which can only be accessed by setBeer and getBeer, but not by anyone else. It doesn’t belong in any execution context, so it can’t be destroyed.

Therefore, closures are prone to memory leaks

This variable is always present as long as the page is not closed, causing a memory leak

Why use closures?

If closures cause memory leaks, why use them at all?

This is because, in some cases, we want variables in certain functions not to be destroyed after the function is executed (I know, there’s a bit of a sword).

Why not make it a global variable? And now you can’t recycle it.

If you create a global variable, it’s easy to contaminate it, rename it, or change it by some function. To prevent it from being tampered with, and to keep it long enough to look like a global variable that can be used at any time, we use closures!

Please note: Closures must be used with caution

Application of closures

Check out a few closure applications, learn about ing

  • Mimic block-level scope

    • An application for timers
    for (var i = 0; 1 < 10; i++) {
          (function (j) {
            setTimeout(function () {
              console.log(j);
            }, 1000 * j)
          })(i)
        }
    Copy the code
    • Prints a set of subscripts for li
    for(var i = 0; i < lis.length; i++) {
    	(function(j) {
    		lis[j].onclick = function() {
    			alert(j)
    		}
    	})(i)
    }
    Copy the code
  • Buried point counter

    • Product lets do a common data collection method of website analysis
    function count() {
    	var num = 0;
    	return function() {
    		return ++num
    	}
    }
    var getNum = count();  // The first place where statistics are needed
    var getNewNum = count(); // The second place for statistics
     // If we count the number of clicks of two buttons
    document.querySelectorAll('button') [0].onclick = function() {
     	console.log('Number of clicks on button 1:'+getNum());
    }
    document.querySelectorAll('button') [0].onclick = function() {
     	console.log('Number of clicks on button 2:'+getNewNum());
    }
    Copy the code
  • Currie,

    • The method of converting a multi-parameter function into a single parameter function makes it more flexible and convenient
    // The original function is used to verify that the text conforms to the specification
    // reg the text passed in to the regular expression TXT that needs to be detected
    function check(reg,txt){
    	return reg.test(txt)
    }
    console.log(check(re of the phone number,13923456789));
    consoleLog (check(re of mailbox,youxiang@163.com));
    
    / / now
    function nowCheck(reg){
    	return function(txt){
    		return reg.test(txt)
    	}
    }
    varIsPhone = nowCheck(re of phone number)console.log(isPhone('13923456789'))
    varIsEmail = nowCheck(re of email)console.log(isEmail('[email protected]'))
    Copy the code

Summary: A quick word about closures

Causes of closures

A local variable in a function is destroyed after the function is executed. Sometimes, when we don’t want the local variable to be destroyed, and we want continuous operations and access from outside, we use closures.

Why not create a global variable instead of a local variable?

Because global variables can be contaminated or modified.

Closures can access their variables because of scope chains, using the idea that nested functions can access variables in the scope of their parent functions.

Closures can cause memory leaks

The variables are always there until the page is closed and cannot be collected by garbage collection or manually cleared.