Closure is a difficult js is also a feature of it, is we must master the ADVANCED FEATURES of JS, so what is the closure? What good is it?
As we all know, js is divided into two kinds, the scope of the global and local, based on the knowledge we are familiar with the scope of the chain, we know that in js scope environment variable access rights are by outside introversion, internal scope can be obtained under the current scope of variables and can get the current contains the current scope under the outer scope of variables, otherwise you can’t, That is, variables in the outer scope cannot be accessed from variables in the inner scope, and variables in different function scopes cannot be accessed from each other. What if we want to access variables in one function with limited access to variables in another function? Closures are designed to address this need, and the essence of closures is to create another function inside one function.
Closures have three characteristics:
-
① Function nested function
-
② Inside a function can refer to parameters and variables outside the function
-
③ Parameters and variables are not collected by the garbage collection mechanism
In this article we will look at the two main forms of closures
Function as return value
In this code, the return value in a() is an anonymous function, which is inside the scope of a(), so it can get the value of the variable name in the scope of A (), and assign this value as the return value to the variable B in the global scope, realizing the value of the variable in the local variable in the global variable
Let’s look at a classic example of a closure
Fn1 =function(){var n = 0… fn1=function(){var n = 0… } and anonymous functions internal reference fn in variable num, so variable num cannot be destroyed, and the variable n is called stylish created every time, so after each fn1 execute it destroyed along with their own variables, thus finally left alone and num, then produce the memory consumption problem here
Let’s take another classic example – timers and closures
Write a for loop that prints out the current number of loops in order
It’s supposed to print 1, 2, 3, 4, 5. Instead, it prints 5 five times. Why? As JS is single-threaded, the timer setTimeout is arranged to queue up for execution in the task queue when executing the for loop. During the waiting process, the for loop is already executed. By the time setTimeout can be executed, the for loop has ended and the value of I has been programmed 5. So print out five 5’s, so how do we change this code to achieve the desired result? (ps: If you change the var in the for loop to let, you can also achieve the desired result.)
A closure is introduced to hold variable I, setTimeout is put into the immediate-execute function, the loop value I in the for loop is passed as a parameter, and after 100 milliseconds, both 1, 2, 3, 4, 5 are printed
So what if we wanted to output a number every 100 milliseconds?
In this code, it is equivalent to starting three timers at the same time. I *100 means that different time is set for the four timers to start at the same time, but the execution time is different. Each timer interval is 100 milliseconds, realizing the effect of printing once every 100 milliseconds.
② The closure is passed as a parameter
If (x>num) {if(x>num) {if(x>num) {if(x>num) {if(x>num) {if(x>num)} Instead, it takes num from the scope in which the function was created, so num takes the global value 15, 30>15, and prints 30
Finally, summarize the pros and cons of closures
benefits
-
① Protect the security of variables in the function, achieve encapsulation, prevent variables into other environments occur naming conflicts
-
② Maintain a variable in memory, can do cache (but use too much is also a disadvantage, consume memory)
-
③ Anonymous self-executing functions can reduce memory consumption
The bad
-
A private variable that is referenced cannot be destroyed, which increases memory consumption and causes memory leaks. The solution is to manually assign a value of null to the variable after using it.
-
(2) Because closures involve cross-domain access, they can lead to performance loss. We can reduce the impact on execution speed by storing cross-scope variables in local variables and accessing local variables directly