Home >Web Front-end >JS Tutorial >Detailed introduction to closure (Closure) in JavaScript_javascript skills

Detailed introduction to closure (Closure) in JavaScript_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:23:32912browse

Closure is an important feature in JavaScript. Its biggest role is to save information during the running of the function. In JavaScript, many features of closures originate from the scope chain during function calls.

Scope chain of function call objects and variables

For each function call in JavaScript, JavaScript will create a local object to store the local variables defined in the function; if there is a nested function defined inside the function, then JavaScript will Define a nested local object on top of an already defined local object. For a function, there are as many layers of nested local objects as there are layers of nested function definitions inside it. This local object is called a "function call object" ("call object" in ECMAScript 3, renamed "declarative environment record" in ECMAScript 5, but personally I think the name in ECMAScript 3 is easier to understand). Take the following function call as an example:


Copy code The code is as follows:

function f(x){
var a = 10;
return a*x;
}
console.log(f(6));//60

In this simple example, when the f() function is called, JavaScript will create a call object of the f() function (let’s call it f_invokeObj). There are two attributes inside the f_invokeObj object: a and x; When running f(), the value of a is 10 and the value of x is 6, so the final return result is 60. The icon is as follows:

When function nesting exists, JavaScript will create multiple function call objects:


Copy code The code is as follows:

function f(x){
var a = 10;
Return a*g(x);
function g(b){
Return b*b;
}
}
console.log(f(6));//360


In this example, when the f() function is called, JavaScript will create a call object (f_invokeObj) of the f() function, which has two internal attributes a and x. The value of a is 10 and the value of x is 6; run f (), JavaScript will parse and define the g() function in the f() function, and create the calling object (g_invokeObj) of g(), which has an internal attribute b, and the b value is the same as the incoming parameter x, which is 6 , so the final return result is 360. The icon is as follows:

As you can see, the function call objects form a chain. When the embedded function g() is running and needs to obtain the variable value, the search will start from the nearest function call object. If it cannot be searched, it will search in further call objects along the function call object chain. This is the so-called "variable scope chain". If the same variable appears in two function call objects, the function will take the variable value in the call object closest to itself:


Copy code The code is as follows:

function f(x){
var a = 10;
Return a*g(x);
function g(b){
var a = 1;
Return b*b*a;
}
}
console.log(f(6));//360, not 3600


In the above example, variable a exists in both the calling object of the g() function (g_invokeObj) and the calling object of the f() function (f_invokeObj) and the value of a is different. When the g() function is run, in g() The value of a used inside the function is 1, while the value of a used outside the g() function is 10. The function call object chain shown in the figure is as follows:

What is a closure?

All functions (functions) in JavaScript are objects, and when a function is defined, a corresponding function call object chain will be generated. A function definition corresponds to a function call object chain. As long as the function object exists, the corresponding function call object exists; once a function is no longer used, the corresponding function call object will be garbage collected; and this one-to-one combination between the function object and the function call object chain, Just call it "closure". In the above example of the f() function and the g() function, there are two closures: the f() function object and the f_invokeObj object form a closure, and the g() function object and the g_invokeObj-f_invokeObj object chain form together The second closure. When the g() function finishes executing, the g() closure is garbage collected because the g() function is no longer used; later, when the f() function finishes executing, f() is closed for the same reason. The package was also garbage collected.

From the definition of closure, we can conclude that all JavaScript functions are closures after definition - because all functions are objects, all functions also have their corresponding calling object chain after execution.

However, where closures really come into their own is in the case of nested functions. Since the inline function is defined when the external function is running, the variable values ​​saved in the closure of the inline function (especially the local variable values ​​of the external function) are the values ​​during this run. As long as the embedded function object still exists, its closure will still exist (the variable values ​​in the closure will not change), thus achieving the purpose of saving information about the function's running process. Consider this example:


Copy code The code is as follows:

var a = "outside";
function f(){
var a = "inside";
function g(){return a;}
Return g;
}
var result = f();
console.log(result());//inside


In this example, when the f() function is run, the g() function is defined and a closure of the g() function is created. The g() closure contains the g_invokeObj-f_invokeObj object chain, thus saving f() The value of variable a during function execution. When the console.log() statement is executed, since the g function object still exists, the g() closure still exists; when running the g function object that still exists, JavaScript will use the g() closure that still exists and Get the value of variable a ("inside") from it.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn