This article introduces the closure in javascript, including understanding of the js closure concept, writing methods and usage of the closure, the main function of the closure, the closure and this object, the knowledge of closures related to memory leaks and the use of closures is very good and has reference value. If you are interested, learn together. 1. What is closures?
A closure is a function that has the right to access variables in another function scope.
Simply put, Javascript allows the use of internal functions-that is, function definitions and function expressions are located in the body of another function. In addition, these internal functions can access all the local variables, parameters, and other declared internal functions declared in their external functions. When one of these internal functions is called outside the external functions that contain them, a closure is formed.
2. Scope of Variables
To understand closures, you must first understand the scope of variables.
Variables have two scopes: global variables and local variables.
The special feature of Javascript is that the function can directly read global variables.
The internal function can access the variables of the external function because the scope chain of the internal function contains the scope of the external function;
It can also be understood that the scope of the internal function is radiating to the scope of the external function;
var n=999;function f1(){ alert(n);}f1(); // 999
On the other hand, local variables in the function cannot be read outside the function.
function f1(){ var n=999;}alert(n); // error
Note that you must use the var command when declaring variables in a function. If you don't need it, you actually declare a global variable!
function f1(){ n=999;}f1();alert(n); // 999
3. Writing and usage of closures
3.1 add some attributes to the Function
function Circle(r) {this.r = r;}Circle.PI = 3.14159;Circle.prototype.area = function() {return Circle.PI * this.r * this.r;}var c = new Circle(1.0);alert(c.area()); //3.14159
3.2 declare a variable and assign a function as a value to the variable
var Circle = function() {var obj = new Object();obj.PI = 3.14159; obj.area = function( r ) {return this.PI * r * r;}return obj;}var c = new Circle();alert( c.area( 1.0 ) ); //3.14159
3.3. This method is widely used and most convenient. Var obj = {} is an empty object.
var Circle={"PI":3.14159,"area":function(r){return this.PI * r * r;}};alert( Circle.area(1.0) );//3.14159
4. Main Functions of closures
Closures can be used in many places. It has two major functions: one is the variable that can be read from the function, and the other is to keep the value of these variables in the memory.
4.1. How do I read local variables from the outside?
For various reasons, we sometimes need to get local variables in the function. However, as we have already said, under normal circumstances, this cannot be done. It can only be implemented through a work und.
That is to define another function within the function.
function f1(){ var n=999; function f2(){ alert(n); // 999 }}
In the code above, function f2 is included in function f1. All local variables in function f1 are visible to f2. But in turn, the local variables in f2 are invisible to f1. This is the unique "chain scope" structure (chain scope) of Javascript language. The sub-object will first look up the variables of all parent objects. Therefore, all variables of the parent object are visible to the child object, and vice versa.
Since f2 can read local variables in f1, As long as f2 is taken as the return value, we can't read its internal variables outside f1!
function f1(){ var n=999; function f2(){ alert(n); } return f2;}var result=f1();result(); // 999
4.2. How to keep the variable value in the memory?
function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2;}var result=f1();result(); // 999nAdd();result(); // 1000
In this Code, the result is actually the f2 function of the closure. It runs twice in total. The first value is 999, and the second value is 1000. This proves that the local variable n in function f1 has been stored in the memory and is not automatically cleared after f1 is called.
Why? The reason is that f1 is the parent function of f2, and f2 is assigned a global variable, which causes f2 to always be in the memory, while f2 depends on f1, therefore, f1 is always in the memory and will not be recycled by the garbage collection mechanism after the call is completed.
Another noteworthy part of this code is "nAdd = function () {n + = 1}". The var keyword is not used before nAdd, therefore, nAdd is a global variable rather than a local variable. Secondly, the value of nAdd is an anonymous function, and this anonymous function itself is also a closure, so nAdd is equivalent to a setter, you can operate the local variables inside the function outside the function.
5. Closure and this object
Using this object in closures may cause some problems. Because the execution of anonymous functions is global, this object usually points to window. The Code is as follows:
Var name = "The window"; var object = {name: "My object", getNameFun: function () {return this. name ;}}}; alert (object. getNameFun () {}); // "The window" (in non-strict Mode)
Store the this object in the external scope in a variable that can be accessed by the closure, so that the closure can access the object. The Code is as follows:
var name = "The window";var object = {name:"My object",getNameFun:function(){var that = this;return function(){return that.name;};}};alert(object.getNameFun(){}); //“My object”
6. Closure and Memory leakage
Specifically, if an HTML element is stored in the scope of the closure, the element cannot be destroyed. As follows:
function assignHandler(){var element = document.getElementById("someElement");element.onclick = function(){alert(element.id);}}
The code above creates a closure that acts as the element event handler, and this closure creates a circular reference. Because the anonymous function saves a reference to the active object of assignHandler (), the reference quantity of element cannot be reduced. As long as the anonymous function exists, the reference number of the element must be at least 1, so the memory occupied by the element will not be recycled.
You can rewrite the code to solve the internal issue that cannot be recycled:
function assignHandler(){var element = document.getElementById("someElement");var id = element.id;element.onclick = function(){alert(id);}element = null;}
In the above Code, the implemented closure does not directly reference the element, and a reference will still be saved in the active object that contains the function. Therefore, it is necessary to set the element variable to null so that the occupied memory can be recycled normally.
7. Notes on using closures
1) because the closure will make the variables in the function be stored in the memory, the memory consumption is very large, so the closure cannot be abused, otherwise it will cause the performance of the web page, memory leakage may occur in IE. The solution is to delete all unused local variables before exiting the function.
2) The closure changes the value of the internal variable of the parent function outside the parent function. Therefore, if you use the parent function as an object, use the closure as its Public Method, and use internal variables as its private value ), be sure not to change the value of the internal variable of the parent function.
The above is a detailed explanation of the Writing Method and function of closures in JavaScript. I hope it will be helpful to you. If you have any questions, please leave a message and I will reply to you in a timely manner. I would like to thank you for your support for PHP chinnet!
For more details about the writing and functions of closures in JavaScript, refer to the PHP Chinese website!