JavaScript anonymous functions and closures

Summary

In front-end JavaScript development, functions and references to their state, lexical environment, form closures.That is, closures allow you to access the scope of an external function from an internal function.In JavaScript, functions generate closures every time they are created.Anonymous functions and closures can be learned together and understood better.In this paper, through some simple small examples, the common use of anonymous functions and closures is briefly described for learning to share. If there are any deficiencies, please correct them.

General function

A common function consists of a fucntion keyword, a function name, (), and a pair of {}, as follows:

1 function box(){
2     return 'Hex';
3 }
4 alert(box());

Anonymous function

As the name implies, an anonymous function is a function without an actual name.Individual anonymous functions cannot be run as follows:

1 function (){
2     return 'Hex';
3 }
4 //Above, error occurs: missing identifier

How can I solve the problem that anonymous functions cannot be executed?There are several methods:

1. Assign anonymous functions to variables as follows:

1 //Assigning anonymous functions to variables
2 var box=function(){
3     return 'Hex';
4 }
5 alert(box());

2. Call functions through self-execution in the following format: (anonymous functions)()

1 (function(){
2     alert('Hex');
3 })();

3. Assign the return value of the anonymous function's self-execution to the variable as follows:

1 var box=(function(){
2     return 'Hex';
3 })();
4 alert(box);//Note: There are no brackets here

4. Or omit the variable as follows:

1 alert((function() {
2     return 'Hex';
3 })());

How do self-executing anonymous functions pass parameters?As follows:

1 (function(age) {
2     alert('Hex--' + age);
3 })(30);

closure

Closure is a combination of a function and the lexical context in which it was created.This environment contains all the local variables that this closure can access when it is created.Simple understanding: Functions are nested inside functions, and sub-functions can access variables within the scope of the parent function.

1. Place an anonymous function inside the function as follows:

 1 function box(){
 2     //closure
 3     return function(){
 4         return 'Hex';
 5     }
 6 }
 7 alert(box()());
 8 //perhaps
 9 var b=box();
10 alert(b());

2. Returning a local variable through a closure has one advantage and one disadvantage: it can be that the local variable resides in memory.

1 function box(){
2     var age=100;//This variable is a local variable of the function and is not accessible externally
3     return function(){
4         return age;
5     }
6 }
7 alert(box()());

Comparing closures with global variables

1. Use global variables to add up as follows:

1 var age=100;
2 function box(){
3     age++;
4 }
5 alert(age);
6 box();
7 alert(age);
8 box();
9 alert(age);

2. Use local variables to add up as follows:

1 function box(){
2     var age=100;
3     age++;
4     return age;
5 }
6 alert(box());//Unable to Accumulate
7 alert(box());//Unable to Accumulate
8 alert(box());//Unable to Accumulate

3. Accumulate using closures as follows:

 1 function box(){
 2     var age=100;
 3     return function(){
 4         age++;
 5         return age;
 6     }
 7 }
 8 var b=box();//Assign return value to b
 9 alert(b());//Achieve Accumulation
10 alert(b());//Achieve Accumulation
11 alert(b());//Achieve Accumulation
12 b=null;//Using closures does not immediately destroy memory at the end of a call, resulting in poor performance,So you need to remove the occupancy

Difference: Global variables can cause naming conflicts and degrade system performance.

Circular Anonymous Function Value Problem

1. The anonymous function value problem in the loop is as follows: arr[0]=0, arr[1]=1... Arr[4]=4 is not implemented

 1 function box(){
 2     var arr=[];
 3     for (var i=0;i<5;i++) {
 4         arr[i]=function(){
 5             return i;
 6         }
 7     }
 8     //The loop ends before the function returns. i=5
 9     return arr;
10 }
11 var b=box();
12 for (var i=0;i<5;i++) {
13     alert(b[i]()); //All returned at this time are 5, not implemented arr[0]=0,arr[1]=1 ...arr[4]=4 Effect
14 }

How can the above questions be optimized?

Method 1 assigns values directly without closures, as shown below:

 1 function box(){
 2     var arr=[];
 3     for (var i=0;i<5;i++) {
 4         arr[i]=i; //Direct assignment
 5     }
 6     //The loop ends before the function returns. i=5
 7     return arr;
 8 }
 9 var b=box();
10 for (var i=0;i<5;i++) {
11     alert(b[i]); 
12 }

Method 2, self-executing through an anonymous function, is as follows:

 1 function box(){
 2     var arr=[];
 3     for (var i=0;i<5;i++) {
 4         arr[i]=(function(num){
 5           //There can be some other logic here
 6           return  num;
 7         })(i);
 8     }
 9     return arr;
10 }
11 var b=box();
12 for (var i=0;i<5;i++) {
13     alert(b[i]); 
14 }

Method 3, reside the variable in memory as follows:

 1 function box(){
 2     var arr=[];
 3     for (var i=0;i<5;i++) {
 4         arr[i]=(function(num){
 5             //There can be some other logic here
 6             return function(){
 7               return num;
 8             };
 9         })(i);
10     }
11     return arr;
12 }
13 var b=box();
14 for (var i=0;i<5;i++) {
15     alert(b[i]()); 
16 }

On the direction of this

Inside the object, this points to the object itself, as follows:

1 var box={
2     getThis:function(){
3         return this;
4     }
5 };
6 alert(box.getThis());//output[object Object] //this here refers to a box object
1 var user='The window';
2 var box={
3     user:'The box',
4     getUser:function(){
5         return this.user;
6     }
7 }
8 alert(box.getUser());//Output: the box 

this in a closure indicates a window object, so the closure points to the window at run time, as follows:

1 var box1 ={
2     getThis:function(){
3         return function(){
4             return this;
5         }
6     }
7 };
8 alert(box1.getThis()()); //output[object Window]//Here this is a window object
 1 var box1={
 2     user:'The box',
 3     getUser:function(){
 4         //The scope here is box1
 5         return function(){
 6             //The scope here is widow
 7             return this.user;
 8         };
 9     }
10 }
11 alert(box1.getUser()());//Output: the window ,Represents closure simulation at run time this point window

How do I get this of the closure to point to the box?There are two ways to do this, as follows:

 1 alert(box1.getUser().call(box1));//object masquerading
 2 //You can box Scope object passed to closure
 3 var box1={
 4     user:'The box',
 5     getUser:function(){
 6         var that=this;
 7         return function(){
 8             return that.user;
 9         };
10     }
11 }
12 alert(box1.getUser()());

Disadvantages: Closures do not release objects and can easily cause memory leaks, as shown below:

 1 function box(){
 2     var a1=document.getElementById('A01');
 3     var txt=a1.innerHTML;
 4     a1.onclick=function(){
 5         //If a1 by null,Error will occur
 6         //alert(a1.innerHTML);//Click on the event to get the content,
 7         alert(txt);
 8     }
 9     //Without the following sentence, the memory will not be able to release the object a1
10     a1=null;//Here you need to manually a1 Release, wait for recycle
11 }
12 box();

Block-level Scope

Imitate block-level scope, object-oriented thinking, encapsulate variables.Ordinary functions do not have the concept of a block-level scope, as follows:

1 function box(){
2     for (var i=0;i<5;i++) {
3     
4     }
5     alert(i);//Output: 5, indicating for Statement block, i Still accessible
6 }
7 box();

How can i be privateized, scoped and inaccessible? Self-execution using anonymous functions makes scoped inaccessible, as follows:

1 function box(){
2     (function(){
3         for (var i=0;i<5;i++) {
4                     
5         }
6     })();
7     //alert(i);//Error: Tip "i" is undefined
8 }
9 box();

Private scope of global variables to reduce naming conflicts for variables as follows:

1 (function(){
2     //Here is the private scope within the global scope
3     var age=100;
4     alert(age);
5 })();
6 //alert(age);////Error: Hint that "age" is undefined

The difference between a normal function and a constructor: uppercase.The properties and functions of the object are of type public as follows:

 1 function Box(){
 2     this.age=100; //This is a public property and cannot be privatized
 3     //Functions are also public functions
 4     this.run=function(){
 5         return 'running....';
 6     }
 7 }
 8 var box=new Box();
 9 alert(box.age); //Accessible by object
10 alert(box.run());//Accessible by object

How do I privatize public attributes?

 1 function Box(){
 2     var age=100;//Private variable, not accessible externally        
 3     function run(){//Private function, not accessible externally
 4         return 'running....';
 5     }
 6     //Private content can be accessed through publicly available access interfaces
 7     this.go=function(){
 8         return age+' '+run();
 9     }
10 }
11 var box=new Box();
12 alert(box.go());

Pass parameters through the constructor as follows:

 1 function Box(v){
 2     var user=v;
 3     this.getUser=function(){
 4         return user;
 5     };
 6     this.setUser=function(v){
 7         user=v;
 8     }
 9 }
10 var box=new Box('Hex');
11 alert(box.getUser());
12 //Object methods can be created multiple times when they are created

Note: Creating objects through constructors assigns different addresses each time they are created.

Static Private Variables

Using static private variables, you can share data as follows:

 1 (function(){
 2     var user=''; //private variable
 3     Box=function(value){//Must be a global constructor, assigning anonymous functions to Box,Otherwise, external inaccessible
 4         user=value;
 5     }
 6     Box.prototype.getUser=function(){
 7         return user;
 8     };
 9     Box.prototype.setUser=function(value){
10         user=value;
11     };
12 })();
13 var box=new Box('AAAA'); //First Instantiation
14 alert(box.getUser());//output AAAA
15 var box2=new Box('BBBB');//Second instantiation
16 alert(box.getUser());//output BBBB

Singleton Object

A singleton is an object that has only one instantiation and can be implemented in two ways.

1. By literal amount, as follows:

1 var box={
2     user:'hex',
3     go:function(){
4         return user+' is running....';
5     }
6 };
7 alert(box.go());

2. It is implemented by returning objects from the self-execution of anonymous functions as follows:

 1 var box=function(){
 2     var user='Hex'; //private variable
 3     function run(){ //Private Functions
 4         return ' is running....';
 5     }
 6     //Return an object
 7     var obj= {
 8         //Public Privilege Method
 9         going:function(){
10             return user+run();
11         }
12     }
13     return obj;
14 }();
15 alert(box.going());

Remarks

Wangyue

Author: Du Fu (Tang)

How about Dai Zongfu?Qilu Qing is over.
Create a beautiful bell and deity, with Yin and Yang at dawn.
Breast-shaking once clouds rise, and the ears fall into the birds.
Ling Ling will be at the top and you will see all the hills at a glance.

Tags: Javascript

Posted on Sun, 08 Mar 2020 12:27:08 -0400 by beselabios