Home  >  Article  >  Web Front-end  >  Sharing the basics of closure based on javascript_Basic knowledge

Sharing the basics of closure based on javascript_Basic knowledge

WBOY
WBOYOriginal
2016-05-16 17:29:11943browse

If you have a good understanding of the basic concepts of scope and functions as independent objects, it will be quite easy to understand the concept of closure and apply it in actual programming practice.

In terms of DOM event processing, most programmers are already using closures without knowing it. In this case, bugs in the JavaScript engine embedded in the browser may cause memory problems. Leaving aside the issue of leakage, even programmers often get confused when debugging themselves.
Use a simple statement to describe the concept of closure in JavaScript: Since in JavaScript, a function is an object, an object is a collection of attributes, and the value of an attribute can be an object, it becomes natural to define a function within a function. If Declare the function inner inside the function func, and then call inner outside the function. This process generates a closure.
Characteristics of closures:
Let’s look at an example first. If you don’t understand the characteristics of JavaScript, it’s difficult to find the reason:

Copy code The code is as follows:

var outter = [];
function clouseTest() {
var array = ["one", " two", "three", "four"];
for (var i = 0; i < array.length; i ) {
var x = {};
x.no = i;
                                                                            Outter.push(x);
}
}
                                                                                                                                                                                                               >          print(outter[2].invoke());
                                                                                                                                                                          ; Many beginners may come up with this answer:

0
1
2
3

However, when running this program, the result is:

4
4
4 4
In fact, at each iteration, the statement x.invoke = function(){print(i);} is not executed, It just constructs a function object with the function body "print(i);", that's all. When i=4, the iteration stops and the external function returns. When outer[0].invoke() is called again, the value of i is still 4, so the invoke of each element in the outer array returns the value of i. :4. How to solve this problem? We can declare an anonymous function and execute it immediately:




Copy the code
The code is as follows:

var outter = [];
function clouseTest2() {
var array = ["one", "two", "three", "four"];
for (var i = 0; i < array.length; i ) {
var x = {};
x.no = i;
x.text = array[i];
x .invoke = function (no) {
                                                                                             ;
outter.push(x);
}
    }
    clouseTest2();
  


In this example, when we assign a value to x.invoke, we first run a function that can return a function, and then Execute it immediately. In this way, each iterator of x.invoke is equivalent to executing a statement like this:


Copy the code The code is as follows ://x == 0
x.invoke = function(){print(0);}
//x == 1
x.invoke = function (){print(1);}
//x == 2
x.invoke = function(){print(2);}
//x == 3
x.invoke = function(){print(3);}


This way you can get the correct result. Closures allow you to reference variables that exist within an external function. However, it does not use the value of the variable when it was created. Instead, it uses the last value of the variable in the external function.
The purpose of closure:

Now that the concept of closure is clear, let’s take a look at the purpose of closure. In fact, by using closures, we can do a lot of things. For example, it can simulate the object-oriented coding style; express the code more elegantly and concisely; and improve the execution efficiency of the code in some aspects.
Cache:
Let’s look at another example. Imagine that we have a function object whose processing is very time-consuming. Each call will take a long time, so we need to calculate The value that comes out is stored. When this function is called, it is first searched in the cache. If it is not found, it is calculated, then the cache is updated and the value is returned. If it is found, the found value is returned directly.
Closure can do exactly this, because it does not release external references, so the value inside the function can be retained.


Copy code The code is as follows:

var CachedSearchBox = (function () {
var cache = {},
count = [];
return {
attachSearchBox: function (dsid ) {
                                              (dsid in cache) {//If the result is in the cache
                                                                                                                                                                                                               ById(dsid);//New
                    cache[dsid] = fsb;//Update cache
                                                         delete cache[count.shift()];
                                                                                                                                                      ;                    if (dsid in cache) {
                                                                                                                                                                                                 }
                                                                                                  ;
var obj2 = CachedSearchBox .attachSearchBox("input1");



Implement encapsulation:





Copy code


The code is as follows:

var person = function(){
//Variable scope is inside the function and cannot be accessed from outside
var name = "default";
return { getName : function(){ return name; }, setName : function(newName){ name = newName;
}
}
}();

print(person.name);//Direct access, the result is undefined
print(person.getName());
person.setName("jack") ;
print(person.getName());



The result is as follows:

undefined
default
jack

Another important use of closures is to implement objects in object-oriented. Traditional object languages ​​provide a class template mechanism, so that different objects (instances of a class) have independent members and states without interfering with each other. Although there is no such mechanism as classes in JavaScript, we can simulate such a mechanism by using closures. Let’s take the example above:



Copy the code
The code is as follows:

function Person(){
var name = "default";

return {
getName : function(){
return name;
},
setName: function(newName){
name = newName;
}
}
};
var john = Person();
print(john.getName()) ;
john.setName("john");
print(john.getName());

var jack = Person();
print(jack.getName());
jack.setName("jack");
print(jack.getName());

The running results are as follows:
default
john
default
jack

Problems that JavaScript closures should pay attention to:
1. Memory leaks:
In different JavaScript interpreter implementations, due to defects in the interpreter itself, Using closures may cause memory leaks. Memory leaks are a serious problem, which will seriously affect the browser's response speed, reduce user experience, and even cause the browser to become unresponsive. JavaScript interpreters all have a garbage collection mechanism, which generally adopts the form of reference counting. If the reference count of an object is zero, the garbage collection mechanism will recycle it. This process is automatic. However, with the concept of closure, this process becomes complicated. In closure, because local variables may need to be used at some point in the future, the garbage collection mechanism will not handle these external references. If a circular reference occurs, that is, object A refers to B, B refers to C, and C refers to A, this situation will cause the garbage collection mechanism to conclude that its reference count is not zero, thus causing a memory leak. .

2. Contextual reference:

Copy code The code is as follows:

$(function(){
var con = $("div#panel");
this.id = "content";
con.click(function(){
alert(this.id);//panel
});
});

What value does alert(this.id) here refer to? Many developers may make wrong judgments based on the concept of closure:
content
The reason is that this.id is assigned the value displayed in the click callback, forming The closure will refer to this.id, so the return value is content. However, in fact, this alert will pop up "panel". The reason is this here. Although the closure can refer to local variables, when it comes to this, the situation is a bit subtle, because the existence of the calling object makes When the closure is called (when the click event of this panel occurs), this here refers to the jQuery object con. The this.id = "content" in the anonymous function is an operation performed on the anonymous function itself. The two this references do not refer to the same object.
If we want to access this value in the event handler, we have to make some changes:
Copy code The code is as follows:

$(function(){
var con = $("div#panel");
this.id = "content";
var self = this;
con.click(function(){
alert(self.id);//content
});
});

In this way, what we save in the event handling function is a reference to an external local variable self, not this. This technique has many practical applications, and we will discuss it in detail in the following chapters. We will discuss more about closures in detail in Chapter 9, including discussing "closures" in other imperative languages, the application of closures in actual projects, and so on.
Attachment: Due to my limited level, it is inevitable that there will be omissions and errors in the article, or the language itself may be inappropriate. Timely corrections and suggestions are welcome. This article is just to inspire others, thank you all!
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