1. What are the writing and usage of closures and closures
1. What is a closure
Closures, the official explanation of closures is: an expression (usually a function) that has many variables and an environment bound to these variables, so these variables are also part of the expression. Features of closures:
1). As a reference to a function variable, it is in an active state when the function returns.
2). A closure is a stack area where no resources are released when a function returns.
Simply put, Javascript allows the use of internal functions - that is, function definitions and function expressions are located in the function body of another function. Moreover, these internal functions can access all local variables, parameters, and other internal functions declared in the external function where they reside. When one of these internal functions is called outside the external function containing them, a closure is formed.
2. Several ways to write and use closures
First of all, we must understand that in JS everything is an object, and a function is a type of object. Let’s first look at the 5 ways to write closures and briefly understand what closures are. A detailed explanation will be given later.
//The first writing method 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());This writing method is nothing special, it just adds some properties to the function.
//The second way of writing 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 ) );This way of writing is to declare a variable and assign a function to a variable as a value.
//The third way of writing var Circle = new Object(); Circle.PI = 3.14159; Circle.Area = function( r ) { return this.PI * r * r; } alert( Circle.Area( 1.0 ) );This method is best understood, which is to new an object and then add properties and methods to the object.
//The fourth way of writing var Circle={ "PI":3.14159, "area":function(r){ return this.PI * r * r; } }; alert( Circle.area(1.0) );This method is used more frequently and is the most convenient. var obj = {} is to declare an empty object.
//The fifth way of writing var Circle = new Function("this.PI = 3.14159;this.area = function( r ) {return r*r*this.PI;}"); alert( (new Circle()).area(1.0) );To be honest, I have never used this writing method, so you can refer to it.
In general, the above methods are more common in the second and fourth, and you can choose according to your habits.
The commonly used Prototype in JS appears in the above code, so what is the use of Prototype? Let's take a look at it below:
var dom = function(){ }; dom.Show = function(){ alert("Show Message"); }; dom.prototype.Display = function(){ alert("Property Message"); }; dom.Display(); //error dom.Show(); var d = new dom(); d.Display(); d.Show(); //errorWe first declare a variable and assign a function to it, because in Javascript each function has a Portotype property, and the object does not. Add two methods, directly add and break the Prototype above, and see the call situation. The analysis results are as follows:
1. The object method defined by the prototype attribute is a static method and can only be called directly with the class name! In addition, this variable cannot be used in this static method to call other properties of the object!
2. The object method defined using the prototype attribute is a non-static method and can only be used after instantiation! This can refer to other properties in the object itself within the method!
Let's look at another code:
var dom = function(){ var Name = "Default"; this.Sex = "Boy"; this.success = function(){ alert("Success"); }; }; alert(dom.Name); alert(dom.Sex);Let’s take a look first, what will be displayed? The answer is that both of them are displayed Undefined, why? This is because in Javascript each function forms a scope, and these variables are declared in the function, so they are in the scope of this function and are inaccessible to the outside. To access variables, you must new instances.
var html = { Name:'Object', Success:function(){ this.Say = function(){ alert("Hello,world"); }; alert("Obj Success"); } };Let’s take a look at this writing method. In fact, this is a “grammatical sugar” in Javascript. This writing method is equivalent to:
var html = new Object(); html.Name = 'Object'; html.Success = function(){ this.Say = function(){ alert("Hello,world"); }; alert("Obj Success");The variable html is an object, not a function, so it does not have a Prototype attribute, and its methods are all public methods, and html cannot be instantiated. Otherwise, the following error will appear:
But it can be assigned to other variables as a value, such as var o = html; we can use it like this:
alert(html.Name);
html.Success();
Speaking of this, is it over? Careful people may ask, how to access the Say method in the Success method? Is it html.Success.Say()?
Of course not. As mentioned above, due to scope restrictions, it cannot be accessed. So you need to access it using the following method:
var s = new html.Success();s.Say();//You can also write to outside html.Success.prototype.Show = function(){ alert("HaHa");};var s = new html.Success();s.Show();Regarding the scope of Javascript, it cannot be explained clearly in one sentence or two. If you are interested, you can find some information online.
2. The purpose of Javascript closures
In fact, by using closures, we can do a lot of things. For example, simulate object-oriented code style; express code more elegantly and concisely; and improve code execution efficiency in some aspects.
1. Anonymous self-executing function
We know that if all variables are not added with the var keyword, the default will be added to the properties of the global object. There are many disadvantages to adding such temporary variables to the global object.
For example: other functions may misuse these variables; causing the global object to be too large and affecting the access speed (because the value of the variable needs to be traversed from the prototype chain).
In addition to using the var keyword every time we use the variable, we often encounter a situation in which some functions only need to be executed once and their internal variables do not need to be maintained, such as the initialization of the UI, so we can use closures:
var data= { table : [], tree : {} }; (function(dm){ for(var i = 0; i < dm.table.rows; i++){ var row = dm.table.rows[i]; for(var j = 0; j < row.cells; i++){ drawCell(i, j); } } })(data);We create an anonymous function and execute it immediately. Since the external cannot refer to the variables inside it, the resource will be released immediately after the function is executed. The key is not to pollute the global object.
2. Result cache
We will encounter many situations in development. Imagine that we have a very time-consuming function object that takes a long time to process each call.
Then we need to store the calculated value. When calling this function, we first look up in the cache. If it cannot be found, we will calculate it, then update the cache and return the value. If it is found, we can directly return the found value. Closures do exactly this because it does not release external references, so that the values inside the function can be preserved.
var CachedSearchBox = (function(){ var cache = {}, count = []; return { attachSearchBox : function(dsid){ if(dsid in cache){//If the result is in the cache return cache[dsid];//Return the object in the cache directly} var fsb = new uikit.webctrl.SearchBox(dsid);//New cache[dsid] = fsb;//Update cache if(count.length > 100){//Security cache size <=100 delete cache[count.shift()]; } return fsb; }, clearSearchBox: function(dsid){ if(dsid in cache){ cache[dsid].clearSelection(); } } } }; })(); CachedSearchBox.attachSearchBox("input");In this way, we will read the object from the cache on the second call.
3. Packaging
var person = function(){ //The scope of the variable is inside the function, and the var name cannot be accessed outside. var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }(); print(person.name);//Access directly, the result is undefined print(person.getName()); person.setName("abruzzi"); print(person.getName());The results are as follows:
undefined
default
abruzzi
4. Implement classes and inheritance
function Person(){ var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }; var p = new Person(); p.setName("Tom"); alert(p.getName()); var Jack = function(){}; //Inherited from Person Jack.prototype = new Person(); //Add private method Jack.prototype.Say = function(){ alert("Hello,my name is Jack"); }; var j = new Jack(); j.setName("Jack"); j.Say(); alert(j.getName());We define Person, it is like a class, we new a Person object, access its method.
Below we define Jack, inherit Person, and add our own methods.
Personal summary:
I used to think that Javascript was just a branch of Java, a scripting language, and it was easy to learn, but now I find that there are really a lot of things to learn. Javascript is much more powerful than we thought.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.