Closure in JavaScript
Give the definition of closure in JavaScript and understand it by examples.
This post was transported from zhihu answer.
And origin question is:
In js, when a function is executed, it will be destroyed, and correspondingly, the scope of this function will also be destroyed. The form of closure is to return the function in the function, then use a variable in the global to accept the returned function, because the global variable will not be destroyed, and this variable holds the address of the returned function, so we can use this return function, because as long as there are variables or other things used inside the function, then this function will not be destroyed. So when we use the returned function in the global scope, then the main function will not be destroyed, the scope naturally exists, we can naturally use the variables in the function, and can save the state. I don't know if I understand it this way, right?
Here is origin answer
The form of closure is to return the function in the function, then use a variable in the global to accept the returned function, because the global variable will not be destroyed, and this variable holds the address of the returned function, so we can use this return function, because as long as there are variables or other things used inside the function, then this function will not be destroyed. So when we use the returned function in the global scope, then the main function will not be destroyed, the scope naturally exists, we can naturally use the variables in the function, and can save the state.
What you said is a so long paragraph, so let me first try to break down your understanding, and then analyze it slowly.
You say
The form of closure is the return function in the function
That is wrong. JavaScript was originally designed with functional programming in mind, where functions are first-class citizens in the language. This means that functions can be stored in variables like any other type, passed as arguments to other functions, or returned as function execution values. The function returns a function, which is determined by the language paradigm. Nothing to do with closures.
So to understand what the form of closure is, we must start with the definition. Its definition is given directly below,
A closure occurs when a function is executed outside of the lexical scope in which it was defined and can also remember and access the lexical scope in which it was defined.
According to the above definition, we can know the two characteristics of the closure,
-
First, it executes outside the lexical scope in which it was defined.
-
Second, it also has access to the lexical scope where it was defined.
It's a bit of a mouthful to say so, so let's give an example to illustrate.
first example,
function fpp() {
var a = 2;
function bar() {
console.log(a);
}
return bar;
}
var baz = foo(); // Hey, this is the effect of closure
The lexical scope of the bar
function is within the foo
function. But if the bar function is called directly outside the foo
function, the compiler cannot find the definition of bar
outside the foo
, and therefore does not recognize bar
, and will throw an error, indicating that bar
is undefined. So if you want to execute the bar
function outside the foo
function, you can use bar
itself as a return value, let the baz
variable outside foo
receive the bar
function, and then execute it. In this way, the compiler can know that bar
is stored in baz
after foo
is generated, so that the identity of bar
is clear: it is a function. It can be executed outside of foo
.
But according to the language setting of JavaScript, when a function is executed, it can access the lexical scope where it is located. For example, functions in the global scope can access global variables. Similarly, when the bar
function is declared, it can access the scope where it is located, that is, within the foo
function. And the scope in the foo
function has a variable a
, then this a variable can be directly accessed by the bar
function during execution.
But isn't this about functions returning functions? Then look at the second example
function foo() {
var a = 2;
function baz() {
console.log(a);
}
bar(baz);
}
function bar(fn) {
fn();
}
The bar
function is declared outside of foo
, baz
is defined inside of foo
, and the foo
function can access bar
. Now pass baz
to the bar
function, and bar
will execute it after receiving it. At this time, baz
is transferred to the scope execution in bar
by passing, and can access a in the original scope, which is a closure. And it doesn't involve the problem of function returning function.
You see, in the first example above, the **bar
function is executed after being stored in the baz
variable outside the lexical scope, and can still access the variable a in the lexical scope, which creates a closure.**In the second example, baz
is passed to bar
through parameters, so that it is executed outside the scope and can access a within the scope. This is also the most essential feature of closures.
You say
Because the global variable will not be destroyed, and this variable holds the address of the returned function, so we can use this returned function, because as long as there are variables or other things used inside the function, then this function will not be used destroy.
You are right in saying that global variables are not destroyed. But I don't understand what you want to say, maybe you want to say, as long as the reference of a function is not destroyed, then this function will not be destroyed? However, in any case, whether the global variable will be destroyed or not has nothing to do with whether the closure will be destroyed...
In the first example above, baz
is defined globally. Stored is a reference to bar. baz
will not be destroyed because it is defined globally, and it does not matter that bar
and foo
will not be destroyed.
So back to the second example
function foo() {
var a = 2;
function baz() {
console.log(a);
}
bar(baz);
}
function bar(fn) {
fn();
}
The bar
function is declared outside of foo
, baz is defined inside of foo
, and the foo
function can access bar
. Now pass baz
to the bar
function, and bar
will execute it after receiving it. At this time, baz
is transferred to the scope execution in bar
by passing, and can access a in the original scope, which is a closure. Here, baz
is executed in the scope of bar
, not globally, and there is no reference to baz
in the global. But this is a closure, so baz
won't be destroyed either.
The closure will not be destroyed, it is determined by the JavaScript interpreter. When the interpreter detects that a closure is generated during execution, the lexical scope where the closure is located will be circled by the interpreter and will never be destroyed. It's not because the closure is referenced globally and will not be destroyed, so the closure will not be destroyed either. It has nothing to do with the global scope.
Understanding closures is a painstaking process. There are many pitfalls in this regard. The terminology of computer programming is more abstract. Therefore, it is recommended that when you come into contact with a concept, it is best to start with the definition and then contact specific examples, rather than start directly with the examples. **Your sentence "the function returns a function" is most likely influenced by some tutorials on the Internet after directly throwing out examples.
Hope my answer is helpful to you.