Detailed explanation of closures in Javascript_Basic knowledge
Foreword: This is still an introductory article. There are several very important language features in Javascript - objects, prototypal inheritance, and closures. Among them, closure is a new language feature for programmers who use the traditional static language C/C. This article will start with examples to introduce the language features of Javascript closures, and combine it with some ECMAScript language specifications to enable readers to have a deeper understanding of closures.
Note: This article is an introductory article. The example materials are compiled from the Internet. If you are an expert, you are welcome to provide technical suggestions and opinions on the article. This article discusses Javascript. I don’t want to do a language comparison. If you are naturally uncomfortable with Javascript, please take a detour.
What is closure
What is a closure? Closure is Closure, which is a new feature that static languages do not have. But closure is not something too complicated to understand. In short, closure is:
A closure is a collection of local variables of a function, but these local variables will continue to exist after the function returns.
Closure means that the "stack" of a function is not released after the function returns. We can also understand that these function stacks are not allocated on the stack but on the heap
When defining another function within a function, a closure will be generated
The second definition above is the first supplementary explanation, extracting the subject, predicate and object of the first definition - closure is the set of 'local variables' of the function. It's just that this local variable can be accessed after the function returns. (This is not an official definition, but this definition should be more helpful for you to understand closures)
As a local variable, it can be accessed by the code within the function. This is no different from a static language. The difference with closures is that local variables can still be accessed by code outside the function after the function execution ends. This means that the function must return a "reference" pointing to the closure, or assign this "reference" to an external variable to ensure that the local variables in the closure can be accessed by external code. Of course, the entity containing this reference should be an object, because in Javascript, except for basic types, everything else is an object. Unfortunately, ECMAScript does not provide relevant members and methods to access local variables in closures. But in ECMAScript, the inner function (inner function) defined in the function object can directly access the local variables of the external function. Through this mechanism, we can complete access to the closure in the following way.
function greeting(name) {
var text = 'Hello ' name; // local variable
// Each time it is called, a closure is generated and the internal function object is returned to the caller
Return function() { alert(text); }
}
var sayHello=greeting("Closure");
sayHello() // The local variable text
is accessed through the closure
The execution result of the above code is: Hello Closure, because the sayHello() function can still access the local variable text defined within it after the greeting function is executed.
Okay, this is the legendary effect of closures. Closures have a variety of application scenarios and modes in Javascript, such as Singleton, Power Constructor and other Javascript modes that are inseparable from the use of closures.
ECMAScript Closure Model
How does ECMAScript implement closures? Those who want to learn more can obtain the ECMAScript specification for research. I will only give a simple explanation here, and the content also comes from the Internet.
When the function of the ECMAscript script is running, each function association has an execution context scene (Execution Context). This execution context scene contains three parts
The LexicalEnvironment
The VariableEnvironment
this binding
The third point, this binding, has nothing to do with closures and will not be discussed in this article. The grammar environment is used to parse variable identifiers used during function execution. We can imagine the grammar environment as an object, which contains two important components, environment record (Enviroment Recode), and external reference (pointer). The environment record contains local variables and parameter variables declared inside the function, and external references point to the context execution scenario of the external function object. The value of this reference in the global context scene is NULL. Such a data structure forms a one-way linked list, with each reference pointing to the outer context scene.
For example, the closure model of our example above should be like this. The sayHello function is at the bottom layer, the upper layer is the greeting function, and the outermost layer is the global scene. As shown below: So when sayHello is called, sayHello will find the value of the local variable text through the context scene, so "Hello Closure" is displayed in the dialog box on the screen. The functions of the variable environment (The VariableEnvironment) and the grammar environment are basically similar. Please refer to the ECMAScript specification document for specific differences.
Sample sequence of closures
Previously, I roughly understood what Javascript closures are and how closures are implemented in Javascript. Below we will help you understand closures more deeply through some examples. There are 5 examples below. The examples come from JavaScript Closures For Dummies (mirror). Example 1: Local variables in closures are references rather than copies
function say667() {
// Local variable that ends up within closure
var num = 666;
var sayAlert = function() { alert(num); }
num ;
Return sayAlert;
}
var sayAlert = say667();
sayAlert()
So the execution result should be 667 instead of 666.
Example 2: Multiple functions bind the same closure because they are defined in the same function.
function setupSomeGlobals() {
// Local variable that ends up within closure
var num = 666;
// Store some references to functions as global variables
gAlertNumber = function() { alert(num); }
gIncreaseNumber = function() { num ; }
gSetNumber = function(x) { num = x; }
}
setupSomeGlobals(); // Assign values to three global variables
gAlertNumber(); //666
gIncreaseNumber();
gAlertNumber(); // 667
gSetNumber(12);//
gAlertNumber();//12
Example 3: When assigning functions in a loop, these functions will be bound to the same closure
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i ) {
var item = 'item' list[i];
result.push( function() {alert(item ' ' list[i])} );
}
Return result;
}
function testList() {
var fnlist = buildList([1,2,3]);
// using j only to help prevent confusion - could use i
for (var j = 0; j < fnlist.length; j ) {
fnlist[j]();
}
}
The execution result of testList is that the item3 undefined window pops up three times, because these three functions are bound to the same closure, and the value of item is the last calculated result, but when i jumps out of the loop, the value of i is 4, so list The result of [4] is undefined.
Example 4: All local variables of the outer function are within the closure, even if this variable is declared after the inner function is defined.
function sayAlice() {
var sayAlert = function() { alert(alice); }
// Local variable that ends up within closure
var alice = 'Hello Alice';
Return sayAlert;
}
var helloAlice=sayAlice();
helloAlice();
The execution result is a pop-up window of "Hello Alice". Even if the local variable is declared after the function sayAlert, the local variable can still be accessed.
Example 5: Create a new closure every time the function is called
function newClosure(someNum, someRef) {
// Local variables that end up within closure
var num = someNum;
var anArray = [1,2,3];
var ref = someRef;
Return function(x) {
num = x;
anArray.push(num);
alert('num: ' num
'nanArray ' anArray.toString()
'nref.someVar ' ref.someVar);
}
}
closure1=newClosure(40,{someVar:'closure 1'});
closure2=newClosure(1000,{someVar:'closure 2'});
closure1(5); // num:45 anArray[1,2,3,45] ref:'someVar closure1'
closure2(-10);// num:990 anArray[1,2,3,990] ref:'someVar closure2'
Application of closure
Singleton:
var singleton = function () {
var privateVariable;
function privateFunction(x) {
...privateVariable...
}
Return {
firstMethod: function (a, b) {
...privateVariable...
},
secondMethod: function (c) {
...privateFunction()...
}
};
}();
This singleton is implemented through closures. Encapsulation of private members and methods is completed through closures. The anonymous main function returns an object. The object contains two methods, method 1 can access private variables, and method 2 can access internal private functions. What needs attention is the '()' at the end of the anonymous main function. Without this '()', the singleton cannot be generated. Because anonymous functions can only return a unique object and cannot be called from other places. This is how to use closures to generate singletons.

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



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.

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.

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.

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 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.

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.

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.

Go language function closures play a vital role in unit testing: Capturing values: Closures can access variables in the outer scope, allowing test parameters to be captured and reused in nested functions. Simplify test code: By capturing values, closures simplify test code by eliminating the need to repeatedly set parameters for each loop. Improve readability: Use closures to organize test logic, making test code clearer and easier to read.
