Closures are a difficult and characteristic feature of Javascript, and many advanced applications rely on closures.
The scope of a variable
To understand closures, you must first understand Javascript’s special variable scope
There are only two types of scope for variables: global variables and local variables.
What makes the Javascript language special is that global variables can be read directly from inside functions.
var n=999;
function f1(){alert(n); } f1();/ / 999
Copy the code
On the other hand, local variables within a function cannot naturally be read outside the function.
function f1(){var n=999; } alert(n);// error
Copy the code
One thing to note here is that when declaring variables inside a function, you must use the var command. If you don’t, you’re actually declaring a global variable!
function f1(){n=999; } f1(); alert(n);/ / 999
Copy the code
How to read local variables from outside?
For a variety of reasons, we sometimes need to get local variables inside a function. However, as mentioned earlier, this is not normally possible and can only be achieved through workarounds.
That is, inside the function, define another function.
function f1(){
var n=999;
function f2(){
alert(n); / / 999}}Copy the code
In the above code, the function f2 is included inside the function f1, and all local variables inside f1 are visible to F2. But the other way around, local variables inside F2 are invisible to F1. This is the Javascript language’s “chain scope” structure, in which child objects look up, level by level, all of the parent’s variables. Therefore, all variables of the parent object are visible to the child object, and vice versa.
Since F2 can read local variables in F1, if f2 is returned, we can read internal variables outside f1.
function f1(){
var n=999;
function f2(){alert (n); }return f2;
}
varResult = f1 (); result();/ / 999
Copy the code
The concept of closures
The f2 function in the previous code section is a closure.
The definition of “closure” in various professional literature is abstract and difficult to understand. My understanding is that closures are functions that can read variables inside other functions.
Because in the Javascript language, only subfunctions inside functions can read local variables, closures can be understood simply as “functions defined inside a function.”
So, in essence, a closure is a bridge between the inside and outside of a function.
Use of closures
Closures can be used in many ways. It is useful for reading variables inside functions, as mentioned earlier, and for keeping their values in memory at all times.
How to understand this sentence? Look at the code below.
function f1(){var n=999; nAdd=function(){n+=1}function f2(){alert (n); }returnf2; }varResult = f1 (); result();/ / 999NAdd bring them any closer (); result();/ / 1000
Copy the code
In this code, result is actually the closure f2 function. It runs twice, the first with a value of 999 and the second with a value of 1000. This proves that the local variable n in function f1 is kept in memory and is not automatically cleared after f1 is called.
Why is that? The reason is that F1 is the parent of F2, and F2 is assigned to a global variable, which results in F2 always being in memory, and f2’s existence depends on F1, so F1 is always in memory and not collected by garbage collection when the call ends.
NAdd =function(){n+=1}; nAdd is a global variable, not a local variable. Second, the value of nAdd is an anonymous function, and the anonymous function itself is a closure, so nAdd is a setter that operates outside the function on local variables inside the function.
Considerations for using closures
1) Because closures will cause variables in functions to be stored in memory, which consumes a lot of memory, so do not abuse closures, otherwise it will cause performance problems of web pages, and may lead to memory leaks in IE. The solution is to remove all unused local variables before exiting the function.
2) Closures change the values of variables inside the parent function outside the parent function. So, if you use a parent function as an object, a closure as its Public Method, and internal variables as its private values, be careful not to arbitrarily change the values of the parent function’s internal variables.
Six, thinking questions
If you can understand the results of the following two pieces of code, you should be able to understand how closures work.
Code snippet one.
var name = "The Window";varobject = {name : "My Object".getNameFunc : function(){return function(){return this.name; }; }}; alert(object.getNameFunc()());// The Window
Copy the code
Code snippet two.
var name = "The Window";varobject = {name : "My Object".getNameFunc : function(){var that = this;return function(){returnthat.name; }; }}; alert(object.getNameFunc()());// My Object
Copy the code
The role of closures
1. Mimic block-level scopes
A block-level scope is a variable defined in a loop, and once the loop ends, the variable is destroyed, and its scope is limited to this small piece. In JavaScript, there is no block-level scope. Because JavaScript doesn’t tell you if a variable has been declared, it can cause naming conflicts. If a variable is defined in the global environment, it will pollute the global environment, so you can use closures to mimic block-level scope.
Function X(num) {function(){for(var I = 0; i < num.length; I++){num++}}).call() // declare that a function is called immediately, the browser will refresh the page error, you can use a small bracket to wrap the whole section of the function. Console.log (I)//undefined} // will be released soon after execution. Crucially, this mechanism does not pollute global objects.Copy the code
In the above code, the closure is the anonymous function that acts as an active variable inside function X and guarantees that its internal variables will be destroyed immediately after execution. This writing method is often used in the global environment, can avoid adding too many global variables and global functions, especially when the development of multiple people, can reduce the naming conflict, so as to avoid pollution of the global environment.
2. Store variables
Another feature of closures is that they can hold variables of external functions, which retain references to the active variables of the external function, so the variables are not released.
function S(){
var a = 1
return {
function(){
renturn a
}
}
}
var d = S() // 100
Copy the code
This notation can be used to save complex values calculated infrequently and save time for each visit.
3. Encapsulate private variables
We can think of a function as a scope. The variables inside the function are private and cannot be referenced externally, but we can access private variables through the closure’s characteristics.
Var person = function(){var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; }}} (); print(person.name); // Undefined print(person.getName()); // default person.setName("abruzzi"); print(person.getName()); // abruzziCopy the code
Link: www.jianshu.com/p/58a22ac2a…