<> preface
Closure is one of the most common interview questions , Many people are asked about the knowledge of closures in the interview , What is the concept of closure ? What are the advantages and disadvantages of closures ? What are the application scenarios of closures ?
My friend was also asked this question during the interview two days ago , There are many answers on the Internet : Some say that a function that can read the internal scope of other functions is a closure , Some say that all functions are closures , Even in global scope , Because it can get variables in the global scope … The answer is also very different , This makes me a little hesitant about the answer , So I went over it again 《 You don't know javascript Volume I 》 and 《javascript Advanced program Fourth Edition 》, Take a look at the explanations of closures in these two books , Record the relevant knowledge , Hope to help you .
<> Initial closure
《 You don't know javascript》 javascript Closures are everywhere in the world , You just need to be able to recognize and embrace it .
Closures are based on lexical scope , A phenomenon that occurs when you write code .
Closures occur when a function can remember and access its lexical scope
function foo(){ var a = 2; function bar(){ console.log(a) //2 } } foo()
In the code above ,bar It is also a closure , Because it can access the variables in its scope . But he's closed foo Inside , It is equivalent to a search rule of lexical scope , Its scope was not found , Go to the previous scope . It's also part of the closure
function foo(){ var a = 2; function bar(){ console.log(a) } return bar } var
baz= foo() baz() //2 ----------- This is the effect of closures
We will bar Function passed out , Then call foo Function is assigned to baz, call baz It's equivalent to calling the internal bar Function , and bar It is equivalent to executing the .foo After function execution , Normally, the internal scope will be destroyed , Garbage collection also frees up memory that is no longer used , But closures can stop that , Give Way foo The internal scope still exists . This is for reference bar The function is anywhere after that , Any time reference
bar Function still holds a reference to this scope , This reference is called a closure .
No matter how we do it bar This function is passed out function foo() { var a = 2; function bar() { console.log
( a ); // 2 } baz( bar); } function baz(fn) { fn(); // Pass it as a parameter This is also a closure } var fn;
function foo() { var a = 2; function bar() { console.log( a ); } fn = baz; //
Direct assignment to global variables fn} function bar() { fn(); // This is also a closure } foo(); baz(); // 2
The above codes , There is a way to pass a function as an argument , There are also functions assigned to a global variable , So that this function can be called outside the lexical scope , It's all closures . Including some timers we usually use , timer , Event listeners use callbacks
function , Are applications of closures function getName(name){ setTimeout( function timer() { console.log(
name); }, 1000 ); } getName(' Xiao Ming ')
// Add an internal function timer Pass on to setTimeout,timer With coverage getName Closure of , And this pair name Reference to
<>for Loops and closures
We use it a lot for loop for (var i=1; i<=5; i++) { setTimeout( function timer() {
console.log( i ); }, i*1000 ); }
In the code above , Normally we want to print 1,2,3,4,5, But it was actually printed five times at a rate of one per second 6,6 Where did it come from ? What is the end condition of this cycle i
be not in <=5, So when the conditions were first established i namely 6, What is printed is the value at the end of the loop ? Why ?
Although this timer Functions are defined once at each iteration , It's equivalent to five definitions , But they are all enclosed under a shared global scope , It's like there's only one i, according to js in setTimeout From the perspective of operation mechanism , It's normal, too .
So what do we have to do with that ? We can create a scope at each iteration , In this case, it is not in a global scope . for (var i=1; i<=5; i++) { (
function() { setTimeout( function timer() { console.log( i ); }, i*1000 ); })();
}
Let's first try to use the self executing function to create the scope .
Still not …
We can create a block level scope at each iteration for (let i=1; i<=5; i++) { setTimeout( function timer() {
console.log( i ); }, i*1000 ); }
We use it es6 In let Defining variables , A block level scope is created at each iteration , This is OK
<> Application scenarios of closure
What are the application scenarios of closures ? Like timers , Callback function , Anti chattering function .... A lot of them use closures We can also encapsulate private variables (function() { // Private variables and private functions
let privateVariable = 10; function privateFunction() { return false; } // Constructors
MyObject= function() {}; // Public and privileged methods MyObject.prototype.publicMethod = function()
{ privateVariable++; return privateFunction(); }; })(); var obj = new MyObject()
obj.publicMethod() //false
Like the one above , We use a self executing function to encapsulate private variables , Create a constructor expression , We're useless var definition , The explanation is a global one , A publicMethod Function method , This function can access the lexical scope of this function , It's just a closure
We can also use module mode to create , Returns a singleton object function singleton() { // Private variables and private functions let privateVariable
= 10; function privateFunction() { return false; } // privilege / Public methods and properties return {
publicProperty: true, publicMethod() { privateVariable++; return privateFunction
(); } }; } var foo = singleton(); foo.publicMethod() //false
singleton Function returns an object , It is equivalent to a module instance , What's in this object publicMethod Function has a closure that covers the internal scope of the module instance ,singleton Functions can also be self executing
<> Summary
When a function can remember and access its lexical scope , Even if the function is executed outside the current lexical scope , And then there's the closure . Closures are also a very powerful tool , Modules can be implemented in various forms .
Closures also have problems , For example, the HTML The element is stored in the scope of a closure , It's like declaring that the element can't be destroyed . Or you put the function return After coming out He gave it to me
window So it's always in memory . Can cause memory leaks . function Handler() { let element =
document.getElementById('element'); let id = element.id; element.onclick = () =>
console.log(id); element = null;//
take element Set to null, Dereference this object , Its reference count is also reduced , So as to ensure that its memory can be recycled at the appropriate time .}
reference material :
《 You don't know javascript》 Volume I
《javascript Advanced programming fourth edition 》
Technology