A Brief analysis of Javascript anonymous function and self executing function

  • 2020-12-16 05:51:18
  • OfStack

Functions are one of the most flexible objects in JavaScript, but the purpose of their anonymous functions is explained here. Anonymous functions: Functions that do not have a function name.

The definition of function can be roughly divided into three ways:

Type 1: This is also the most common type


function double(x){ 
return 2 * x; 
}

Option 2: This method uses the Function constructor and takes both the argument list and the function body as strings, which is inconvenient and not recommended.


var double = new Function('x', 'return 2 * x;');

Third:


var double = function(x) { return 2* x; }

Note that the function to the right of "=" is an anonymous function that is assigned to the variable square after the function is created.

Creation of anonymous functions

The first way is to define the square function as described above, which is also one of the most common ways.

The second way:


(function(x, y){ 
alert(x + y); 
})(2, 3);

Here, an anonymous function is created (within the first parenthesis), and the second parenthesis is used to call the anonymous function and pass in parameters. Parentheses are expressions that have a return value, so you can add a pair of parentheses after them to make them execute.

Anonymous self-executing functions

1. What is a self-executing anonymous function ?

It refers to a function of form such as: (function {// code})();

2. The question

Why (function {// code})(); Can be executed while function {// code}(); But it will report an error ?

3. The analysis

(1) First of all, the difference between the two should be clear:
(function {// code}) is the expression, and function {// code} is the function declaration.
(2) Secondly, the characteristics of js" pre-compiled ":
js interprets function declarations during the "precompile" phase, but ignores tables.
(3). When js executes to function() {//code}(); Since function() {//code} has been explained in the "precompile" phase, js will skip function(){//code} and attempt to execute (); , so it will report an error;
When js (function {// code})(); , since (function {// code}) is an expression, js will solve it to get the return value. Since the return value is a function, it encounters (). , it will be executed.

In addition, the way functions are converted to expressions does not necessarily depend on the grouping operator (), we can also use the void operator, ~ operator,! Operator...

Such as:


!function(){ 
alert(" The alternative anonymous function executes itself "); 
}();

Anonymous functions and closures

The English word for closures is closure, which is a very important part of JavaScript, because using closures can greatly reduce the amount of code we have, make our code look clearer, etc., etc., etc. In short, they are 10 points powerful.

What a closure means: A closure is simply a nesting of functions in which the inner function can use all the variables of the outer function, even after the outer function has been executed (this involves the JavaScript scope chain).


function checkClosure(){ 
var str = 'rain-man'; 
setTimeout( 
function(){ alert(str); } // This is a 1 Anonymous function  
, 2000); 
} 
checkClosure();

This example looks simple, 10 points under the careful analysis of its implementation process there are still a lot of knowledge points: checkClosure function execution is instantaneous (maybe it just 0.00001 milliseconds), the function of checkClosure str created a variable in the body, in checkClosure after str has not been released, this is because the anonymous function being in setTimeout str reference for that. str is not released until 2 seconds after the anonymous function in the body has been executed.

Optimize code with closures:


function forTimeout(x, y){ 
alert(x + y); 
} 
function delay(x , y , time){ 
setTimeout('forTimeout(' + x + ',' + y + ')' , time); 
} 
/** 
*  The above delay function 10 They are hard to read and not easy to write, but they can make the code cleaner if you use closures  
* function delay(x , y , time){ 
* setTimeout( 
* function(){ 
* forTimeout(x , y) 
* } 
* , time); 
* } 
*/

The most useful use of anonymous functions is to create closures (a feature of the JavaScript language), and you can also build namespaces to reduce the use of global variables.


var oEvent = {}; 
(function(){ 
var addEvent = function(){ /* The implementation of the code is omitted */ }; 
function removeEvent(){} 

oEvent.addEvent = addEvent; 
oEvent.removeEvent = removeEvent; 
})();

In this code, the functions addEvent and removeEvent are both local variables, but we can use the global variable oEvent, which greatly reduces the use of global variables and enhances the security of web pages.

We want to use this code:


oEvent.addEvent(document.getElementById('box') , 'click' , function(){});
var rainman = (function(x , y){ 
return x + y; 
})(2 , 3); 
/** 
*  I can also write it in the following form, because alpha 1 Parentheses are just for reading purposes, but the following writing format is not recommended.  
* var rainman = function(x , y){ 
* return x + y; 
* }(2 , 3);

Here we create a variable, rainman, and initialize it to 5 by calling the anonymous function directly, a trick that is sometimes 10 points useful.


var outer = null; 
(function(){ 
var one = 1; 
function inner (){ 
one += 1; 
alert(one); 
} 
outer = inner; 
})(); 
outer(); //2 
outer(); //3 
outer(); //4

The variable one in this code is a local variable (because it is defined within a function), so it is not externally accessible. But here we've created the inner function, which has access to the variable one; The global variable outer is also referred to inner, so three calls to outer will pop up an increasing result.

Pay attention to

Closures 1 allow the inner function to refer to a variable in the parent function, but that variable is the final value


var double = new Function('x', 'return 2 * x;');
0

You'll notice that when you mouse over each one < li > When it comes to elements, it always pops up a 4, not the subscript that we're expecting. Why is that? This is already covered in the notes. Obviously, this explanation is too simplistic. When an mouseover event calls a listening function, the first thing to do is to write an anonymous function (function(){alert(i); }) To find whether i is defined internally, the result is not defined; So it looks up, and the result is defined, and the value of i is 4 (i after the loop); So, you end up with a 4 every time it pops up.

Solution 1:


var double = new Function('x', 'return 2 * x;');
1

Solution 2:


var double = new Function('x', 'return 2 * x;');
2

Solution 3:


function eventListener(list, index){ 
list.onmouseover = function(){ 
alert(index); 
}; 
} 
var lists = document.getElementsByTagName('li'); 
for(var i = 0 , len = lists.length ; i < len ; i++){ 
eventListener(lists[ i ] , i); 
}

2 Memory leak

Using closures can cause memory leaks in the browser and, in severe cases, browser death


Related articles: