1. What is a closure? The official explanation of the closure is: an expression (usually a function) with many variables and an environment bound to these variables ), therefore, these variables are part of the expression. Closure features: 1. As a reference to a function variable, a function is activated when it is returned. 2. A closure is a stack that does not release resources when a function returns. To put it simply... 1. What are the writing methods and usage of closures and closures?
1. What is a closure?
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 part of the expression. Closure features:
1. As a reference to a function variable, the function is activated when it is returned.
2. A closure is a stack that does not release resources when a function returns.
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. Writing and usage of closures
First, you must understand that everything in JS is an object, and a function is a type of object. Next, let's take a look at the five writing methods of closures to briefly understand what closures are. It will be explained in detail later.
// There are 1st writing methods: 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 ());
There is nothing special about this writing method, just adding some attributes to the function.
// There are 2nd writing methods: var Circle = function () {var obj = new Object (); obj. PI = 3.14159; obj. area = function (r) {return this. PI * r;} return obj;} var c = new Circle (); alert (c. area (1.0 ));
This statement declares a variable and assigns a function as a value to the variable.
// Write var Circle = new Object (); Circle. PI = 3.14159; Circle. area = function (r) {return this. PI * r;} alert (Circle. area (1.0 ));
This method is better understood as a new object, and then adds attributes and methods to the object.
// 4th writing methods var Circle = {"PI": 3.14159, "area": function (r) {return this. PI * r ;}}; alert (Circle. area (1.0 ));
This method is widely used and most convenient. Var obj = {} is an empty object.
// There are 5th writing methods: var Circle = new Function ("this. PI = 3.14159; this. area = function (r) {return r * this. PI;} "); alert (new Circle ()). area (1.0 ));
To be honest, I have never used this method. You can refer to it.
In general, the above several methods are common in 2nd and 4th. You can choose one based on your habits.
The Prototype commonly used in JS is shown in the code above. What is Prototype used? Let's take a look:
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(); //error
We first declare a variable and assign it to a function, because in Javascript, each function has a Portotype attribute, but the object does not. Add two methods, respectively add and add to break the Prototype above, to see the call situation. The analysis results are as follows:
1. The object method defined by the prototype attribute is not used. It is a static method and can only be called directly by 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 by the prototype attribute is non-static and can only be used after instantiation! In this method, other attributes of the object can be referenced!
Let's take a look at the code below:
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. What will it show? The answer is Undefined. Why? This is because every function in Javascript forms a scope, and these variables are declared in the function, so they are in the scope of the function and cannot be accessed externally. To access variables, you must create a new instance.
var html = { Name:'Object', Success:function(){ this.Say = function(){ alert("Hello,world"); }; alert("Obj Success"); } };
Let's take a look at this writing method. This is actually a "syntactic sugar" of Javascript, which is equivalent:
var html = new Object(); html.Name = 'Object'; html.Success = function(){ this.Say = function(){ alert("Hello,world"); }; alert("Obj Success");
Variable html is an object, not a function, so there is no Prototype attribute, and its methods are also public methods. html cannot be instantiated. Otherwise, the following error occurs:
But it can be assigned to other variables as values, such as var o = html; we can use it like this:
alert(html.Name); html.Success();
Speaking of this, are you finished? Careful people will ask how to access the Say method in the Success method? Is it html. Success. Say?
Of course not. As mentioned above, access is not allowed due to the limitation of the scope. So use the following method to access:
Var s = new html. success (); s. say (); // You can also write html. success. prototype. show = function () {alert ("HaHa") ;}; var s = new html. success (); s. show ();
The question about the Javascript scope is not clear in one or two sentences. If you are interested, you can find some information on the Internet.
Ii. Use of Javascript closures
In fact, we can do a lot of things by using closures. For example, it simulates the object-oriented code style. It is more elegant and concise to express the Code. In some aspects, it improves the code execution efficiency.
1. Anonymous self-executed Functions
We know all the variables. If the var keyword is not added, it will be added to the global object attribute by default. There are many disadvantages for adding such temporary variables to the global object,
For example, other functions may misuse these variables, resulting in a huge global object that affects access speed (because the value of the variable needs to be traversed from the prototype chain ).
Except that variables are used with the var keyword each time, we often encounter such a situation that some functions only need to be executed once and internal variables do not need to be maintained,
For example, we can use the closure to initialize the UI:
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 have created an anonymous function and executed it immediately. Because the external system cannot reference its internal variables, resources will be released immediately after the function is executed. The key is not to pollute the global object.
2. Result Cache
We may encounter many situations during development. Suppose we have a function object that takes a long time to process, and each call will take a long time,
Then we need to store the calculated value. When calling this function, we first find it in the cache. If it cannot be found, we will perform the calculation, then update the cache and return the value, if yes, you can directly return the value you have found. The closure can do this because it does not release external references, so that the internal values of the function can be retained.
Var CachedSearchBox = (function () {var cache ={}, count = []; return {attachSearchBox: function (dsid) {if (dsid in cache) {// return cache [dsid] if the result is in the cache; // directly return the cached object} var fsb = new uikit. webctrl. searchBox (dsid); // create cache [dsid] = fsb; // update cache if (count. length> 100) {// the size of the cache <= 100 delete cache [count. shift ()] ;}return fsb ;}, clearSearchBox: function (dsid) {if (dsid in cache) {cache [dsid]. clearSelection () ;}};}) (); CachedSearchBox. attachSearchBox ("input ");
In this way, the object will be read from the Cache during the second call.
3. Encapsulation
Var person = function () {// The variable scope is inside the function. external access to 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 ("abruzzi"); print (person. getName (); the result is as follows: undefined default abruzzi
4. Implementation class 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 the 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 have defined Person, which is like a class. We use a new Person object to access it.
Next we define Jack, inherit the Person, and add our own method.
The above section details the in-depth parsing of Javascript closures and code implementation methods. For more information, see other related articles in the first PHP community!