Deeply analyze the function and implementation method of Javascript closure

  • 2021-07-02 23:07:04
  • OfStack

1. What are closures and how they are written and used
1. What is a closure
Closure, the official interpretation of closure is: an expression (usually a function) that has many variables and the environment in which these variables are bound, so these variables are also part of the expression. Characteristics of closures:
1). As a reference to a function variable, it is active when the function returns.
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 in the body of another function. Moreover, these inner functions have access to all local variables, parameters, and other inner functions declared in the outer function in which they are located. When one of these inner functions is called outside the outer function that contains them, a closure is formed.
2. Several writing and usage of closures
First of all, we should understand that in JS, 1 cut is an object, and a function is a kind of object. Let's look at five ways to write closures under 1, and simply understand what closures are under 1. It will be explained in detail later.


// No. 1 1 Kinds of writing  
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, just adding 1 attribute to the function.


// No. 1 2 Kinds 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 is written by declaring a variable and assigning a function to the variable as a value.


// No. 1 3 Kinds 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, that is, new 1 object, and then add properties and methods to the object.


// No. 1 4 Kinds of writing  
var Circle={ 
  "PI":3.14159, 
 "area":function(r){ 
     return this.PI * r * r; 
    } 
}; 
alert( Circle.area(1.0) );

This method is widely used and most convenient. var obj = {} is to declare an empty object.


// No. 1 5 Kinds 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 tell the truth, I have never used this writing, so you can refer to 1.
Generally speaking, the above methods, No.2 and No.4, are more common, so you can choose according to your habits.
In the above code, Prototype, which is commonly used in JS, appears, so what's the use of Prototype? Let's take a look at 1:


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 a function, because in Javascript each function has an Portotype attribute, while the object does not. Add two methods, directly add and add break Prototype above, to see the call. The analysis results are as follows:
1. Object methods that do not use prototype attributes are static methods and can only be called directly with class names! In addition, the this variable cannot be used in this static method to call other properties of the object!
2. The object method defined by prototype attribute is a non-static method, which can only be used after instantiation! Its method can refer to other attributes in the object itself by this!
Let's look at another piece of 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 it show? The answer is that both show Undefined. Why? This is because each function in Javascript forms a scope, and these variables are declared in the function, so they are in the scope of this function and cannot be accessed externally. To access variables, you must have new1 instances.


var html = {
    Name:'Object',
    Success:function(){
      this.Say = function(){
          alert("Hello,world");
      };
      alert("Obj Success");
    }
  };

Let's take a look at this writing. In fact, this is a "grammar sugar" of Javascript. This writing 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 there is no Prototype attribute, and its methods are all public methods, so html cannot be instantiated. Otherwise, the following error will occur:

But it can be assigned as a value to other variables, such as var o = html; We can use it like this:
alert(html.Name);
html.Success();
Having said that, is it over? 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, it is inaccessible due to the limitation of scope. So you want to access it in the following way:


var s = new html.Success();
s.Say();

// You can also write it outside 
html.Success.prototype.Show = function(){
  alert("HaHa");
};
var s = new html.Success();
s.Show();

On the Javascript scope of the problem, not 1 or 2 sentences can be said clearly, interested people can look for some information on the Internet.
2. Use of Javascript closures
In fact, we can do a lot of things by using closures. For example, simulate the object-oriented code style; Express the code more elegantly and concisely; Improve the efficiency of code execution in some aspects.

1. Anonymous self-executing function
We know that all variables, without the var keyword, will be added to the properties of global objects by default. There are many disadvantages to adding such temporary variables to global objects.
For example, other functions may misuse these variables; As a result, the global object is too large, which affects the access speed (because the values of variables need to be traversed from the prototype chain).
In addition to using the var keyword every time we use variables, we often encounter such a situation in reality, that is, some functions only need to be executed once, and their internal variables do not need to be maintained, such as the initialization of UI, so we can use closures:


// No. 1 2 Kinds 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 ) );

0

We created an anonymous function and executed it immediately. Because the variables inside it cannot be referenced externally, the resources will be released immediately after the function is executed. The key is not to pollute the global objects.

2. Result caching
We're going to run into a lot of situations in our development. Imagine that we have a function object that takes a lot of time to process and that each call takes a lot of time,
Then we need to store the calculated value. When calling this function, we first look in the cache. If we can't find it, we will calculate it, then update the cache and return the value. If we find it, we can directly return the found value. Closures do just that, because they don't release external references, so the values inside the function can be preserved.


// No. 1 2 Kinds 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 ) );

1

In this way, on the second call, we will read the object from the cache.

3. Packaging


// No. 1 2 Kinds 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 ) );

2

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(){};
  // Inherit from Person
  Jack.prototype = new Person();
  // Add a 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, which is like a class, we new1 Person objects, accessing its methods.
Below we define Jack, inherit Person, and add our own methods.
Personal summary:
Previously thought Javascript is only a branch of Java, is a scripting language, easy to learn, now found to learn a lot of things really. Javascript is much more powerful than we thought.


Related articles: