1 introduction
If you can read my previous article to understand features such as variable promotion from JS implementation mechanism, I believe you can have more thinking ~
The use of closures is still a lot, I learned when learning React hook also used JavaScript closure mechanism, so I come here to summarize learning.
Closure: return function B from function A, and then call it elsewhere, so that B can access the variables in function A, even after function A has been destroyed.
var local = 'Stop it, Kobayashi.';
function foo() {
var local = 1;
function bar() {
local++;
return local;
}
return bar;
}
var f1 = foo();
console.log(f1());/ / 2
console.log(f1());/ / 3
console.log(f1());/ / 4
var f2 = foo();// The newly defined function is separated from the one above, so the output below is 2, not 4
console.log(f2());/ / 2
console.log('local', local);// There is no closure as the interface, only access to the global variable local
Copy the code
The execution result is shown as follows:
1.1 purpose
This article mainly addresses two issues:
- Deepen your understanding of closures
- Understand the relationship between closures and garbage collection mechanisms
Normally, when foo executes, the scope is destroyed, and the garbage collector frees the memory. The closure miraculously keeps foo’s scope alive, and fn1 still holds a reference to that scope, which is called the closure.
2 Garbage removal mechanism
Take a closer look at the code at the beginning of the article: Don’t you have doubts? I have. Why do f1 and f2 retrieve variables independently of each other? Why does f1 repeatedly return 2,3,4…. Instead of 2? Aren’t functions destroyed after execution?
First of all, f1 and f2 are the results of the separate execution of the foo function. The functions have scope, which is equivalent to the local variable declared separately in the two scopes. Of course, they are independent of each other.
The second problem: this is actually related to the reference count of our garbage collection mechanism. If a variable’s reference is not zero, it is not collected by garbage collection. The reference is called. In this case, f1 refers to foo, so f1 is executed using the same local.
Look at a classic closure
for (var i = 1; i <= 10; i++) {
console.log(i)/ / print 1 to 10
setTimeout(function () {
console.log(i);// Print 10 11s
}, 1000);
}
for (var i = 1; i <= 10; i++) {
(function () {
var j = i;
setTimeout(function () {
console.log(j);
}, 1000); }) (); }/ / print 1 to 10
for (let i = 1; i <= 10; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
}/ / print 1 to 10
Copy the code
3.1 cycle 1
In the first for loop, the top can print out the 1 through 10 as we want, but in the timer, it prints out the 10 11s
Cause: setTimeout is asynchronous and will not be executed until the synchronization is complete according to the browser’s event loop mechanism. But by this time, I has already increased to 11. As to why 11 is not 10, you can learn the difference between the front ++ and the back ++
3.2 cycle 2
In the second for loop, we use the immediate-execution function. The immediate-execution function is synchronous, and the function is also scoped. We declare a variable j to hold the I of each iteration. One small detail: j needs to be declared with let or var, or it’s a global variable.
3.3 cycle 3
For the third for loop, we use let and block-level scope. I =1, I =1, I =1, I =1, I =1, I =1, I =1, I =1, I =1, I =1 The “I” is declared by the “let”. The current “I” is only valid for the round. The “I” is a new variable for each round
4. Pros and cons of closures
Advantage: The closure feature gives global access to the local scope, which makes it possible to set private variables and methods
Disadvantages: Closures cause variables in a function to be stored in memory, which is memory intensive.
Because of the reason of knowledge reserve, can not write like a lot of big guy inside the thorough, welcome big guy guide!