Functions are one of the most flexible types of objects in JavaScript, and this is just how anonymous functions can be used. Anonymous functions: functions that have no function name.

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

The first: this is also the most conventional

function double(x){    
    return 2 * x;       
}Copy the code

Second: this method uses the Function constructor, which uses both the argument list and the Function body as strings, which is inconvenient and not recommended.

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

The third:

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

Note that the function to the right of “=” is an anonymous function. After creating the function, assign it to the variable square.

Creation of anonymous functions

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

The second way:

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

An anonymous function is created (in the first parenthesis), and the second parenthesis is used to call the anonymous function, passing in arguments. Parentheses are expressions, and expressions return values, so you can add a pair of parentheses after them to make them execute.

A self-executing anonymous function

1. What are self-executing anonymous functions? It is a function that looks like this: (function {// code})();

(function {// code})(); Function {// code}(); And you get an error?

Function {// code} = function {// code} = function {// code} = function {// code} Second, js” precompiled “features: in the” precompiled “phase, JS will interpret function declarations, but will ignore table expressions. Function () {//code}(); Because function(){//code} has been interpreted in the “precompiled” phase, js skips function(){//code} and tries to execute (); , so an error will be reported; Function {// code})(); If (function {// code}) is an expression, js will evaluate it and get the return value. If (function {// code}) is a function, js will get the return value. “Is executed.

In addition, the grouping operator () is not required to convert a function to an expression. We can also use the void operator, ~ operator,! Operator…

! Function (){alert(" anonymous function execution "); } ();Copy the code

Anonymous function andclosure

The word for closure is closure, and this is a very important part of JavaScript knowledge because using closures can greatly reduce the amount of code we need to write, make our code look cleaner, etc.

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

function checkClosure(){ var str = 'rain-man'; setTimeout( function(){ alert(str); } // This is an anonymous function, 2000); } checkClosure();Copy the code

This example looks very simple, but there are a lot of points about how to execute it: The execution of the checkClosure function is instantaneous (perhaps in 0.00001 milliseconds). A variable STR is created inside the checkClosure function and is not released after the closure is executed. This is because the anonymous function in setTimeout has a reference to STR. The STR is released 2 seconds later after the anonymous function is executed.

Optimizing code with closures:

function forTimeout(x, y){ alert(x + y); } function delay(x , y , time){ setTimeout('forTimeout(' + x + ',' + y + ')' , time); } /** * The delay function above is very difficult to read and write, * function delay(x, y, time){* setTimeout(* function(){* forTimeout(x, y) *} *, time); *} * /Copy the code

The biggest 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(){/* function removeEvent(){} oEvent.addEvent = addEvent; oEvent.removeEvent = removeEvent; }) ();Copy the code

In this code, the functions addEvent and removeEvent are local variables, but we can use the global variable oEvent, which greatly reduces the use of global variables and enhances the security of the web page. Oevent.addevent (document.getelementById (‘box’), ‘click’, function(){});

var rainman = (function(x , y){ return x + y; }) (2, 3); / * * * can also be written in the form below, because the first brackets just help us to read, but do not recommend using the following the writing format. * var rainman = function(x , y){ * return x + y; *} (2, 3);Copy the code

Here we create a variable called Rainman and initialize it to 5 by calling an anonymous function directly, a trick that is sometimes useful.

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

The variable one in this code is a local variable (because it is defined within a function) and is therefore not externally accessible. But here we create the inner function, which accesses the variable one; The global variable outer also references inner, so three calls to outer pop up incrementing results.

The 1 closure allows an inner function to reference a variable in the parent function, but that variable is the final value

/ * * * *
         
    *
  • one
  • *
  • two
  • *
  • three
  • *
  • one
  • *
*/ var lists = document.getElementsByTagName('li'); for(var i = 0 , len = lists.length ; i < len ; i++){ lists[ i ].onmouseover = function(){ alert(i); }; } Copy the code

You’ll notice when you mouse over each one

  • Element always pops up 4 instead of the expected element index. Why is that? The final value is explained in the notes. Function (){alert(I); function(){alert(I); }) internal check to see if I is defined, result is not defined; So it looks up, and it finds that it’s defined, and the value of I is 4 (the value of I after the loop); So you end up with a 4 every time.
  • Solution 1:

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

    Solution 2:

    var lists = document.getElementsByTagName('li'); for(var i = 0, len = lists.length; i < len; i++){ lists[ i ].$index = i; // List [I]. Onmouseover = function(){alert(this.$index); }; }Copy the code

    Solution three:

    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);  
    }Copy the code

    2 Memory Leaks

    Using closures is a very easy way to leak the browser’s memory, and in some cases, the browser can hang.