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

Detailed introduction to closure (Closure) in JavaScript_javascript skills

May 16, 2016 pm 04:23 PM
javascript Closure

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 of this Website
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

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What is the meaning of closure in C++ lambda expression? What is the meaning of closure in C++ lambda expression? Apr 17, 2024 pm 06:15 PM

In C++, a closure is a lambda expression that can access external variables. To create a closure, capture the outer variable in the lambda expression. Closures provide advantages such as reusability, information hiding, and delayed evaluation. They are useful in real-world situations such as event handlers, where the closure can still access the outer variables even if they are destroyed.

How to implement closure in C++ Lambda expression? How to implement closure in C++ Lambda expression? Jun 01, 2024 pm 05:50 PM

C++ Lambda expressions support closures, which save function scope variables and make them accessible to functions. The syntax is [capture-list](parameters)->return-type{function-body}. capture-list defines the variables to capture. You can use [=] to capture all local variables by value, [&] to capture all local variables by reference, or [variable1, variable2,...] to capture specific variables. Lambda expressions can only access captured variables but cannot modify the original value.

What are the advantages and disadvantages of closures in C++ functions? What are the advantages and disadvantages of closures in C++ functions? Apr 25, 2024 pm 01:33 PM

A closure is a nested function that can access variables in the scope of the outer function. Its advantages include data encapsulation, state retention, and flexibility. Disadvantages include memory consumption, performance impact, and debugging complexity. Additionally, closures can create anonymous functions and pass them to other functions as callbacks or arguments.

Solve the memory leak problem caused by closures Solve the memory leak problem caused by closures Feb 18, 2024 pm 03:20 PM

Title: Memory leaks caused by closures and solutions Introduction: Closures are a very common concept in JavaScript, which allow internal functions to access variables of external functions. However, closures can cause memory leaks if used incorrectly. This article will explore the memory leak problem caused by closures and provide solutions and specific code examples. 1. Memory leaks caused by closures The characteristic of closures is that internal functions can access variables of external functions, which means that variables referenced in closures will not be garbage collected. If used improperly,

The impact of function pointers and closures on Golang performance The impact of function pointers and closures on Golang performance Apr 15, 2024 am 10:36 AM

The impact of function pointers and closures on Go performance is as follows: Function pointers: Slightly slower than direct calls, but improves readability and reusability. Closures: Typically slower, but encapsulate data and behavior. Practical case: Function pointers can optimize sorting algorithms, and closures can create event handlers, but they will bring performance losses.

How are closures implemented in Java? How are closures implemented in Java? May 03, 2024 pm 12:48 PM

Closures in Java allow inner functions to access outer scope variables even if the outer function has exited. Implemented through anonymous inner classes, the inner class holds a reference to the outer class and keeps the outer variables active. Closures increase code flexibility, but you need to be aware of the risk of memory leaks because references to external variables by anonymous inner classes keep those variables alive.

Chained calls and closures of PHP functions Chained calls and closures of PHP functions Apr 13, 2024 am 11:18 AM

Yes, code simplicity and readability can be optimized through chained calls and closures: chained calls link function calls into a fluent interface. Closures create reusable blocks of code and access variables outside functions.

Summary of the advantages and disadvantages of golang anonymous functions and closures Summary of the advantages and disadvantages of golang anonymous functions and closures May 05, 2024 am 09:54 AM

Anonymous functions are concise and anonymous, but have poor readability and are difficult to debug; closures can encapsulate data and manage state, but may cause memory consumption and circular references. Practical case: Anonymous functions can be used for simple numerical processing, and closures can implement state management.

See all articles