Home  >  Article  >  Web Front-end  >  Anonymous functions and self-execution in Javascript

Anonymous functions and self-execution in Javascript

高洛峰
高洛峰Original
2016-10-13 10:21:31981browse

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

The first one: This is also the most conventional one

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

The second one: This method uses the Function constructor, taking both the parameter list and the function body as String is very inconvenient and is not recommended to be used.

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

The third type:

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

Note that the function on the right side of "=" is an anonymous function. After creating the function, the function is assigned to the variable square.

Creation of anonymous functions

The first way: Define the square function as mentioned above, which is also one of the most commonly used ways.

Second way:

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

An anonymous function is created here (inside the first bracket), and the second bracket is used to call the anonymous function and pass in the parameters. Parentheses are expressions, and expressions have return values, so you can add a pair of parentheses at the end to let them execute.

Self-executing anonymous function

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

2. Question
Why (function {// code})(); can be executed, while function {// code} (); but will report an error?

3. Analysis
(1). First of all, we must understand the difference between the two:
(function {// code}) is an expression, function {// code} is a function declaration.
(2). Secondly, the characteristics of js "precompilation":
In the "precompilation" stage, js will interpret function declarations, but ignore expressions.
(3). When js is executed to function() {// code}();, since function() {//code} has been interpreted in the "pre-compilation" stage, js will skip function(){//code} and try to execute ();, so an error will be reported ;
When js executes (function {// code})();, since (function {// code}) is an expression, js will solve it to get the return value. Since the return value is a function, When (); is encountered, it will be executed.

In addition, the method of converting a function into an expression does not necessarily rely on the grouping operator (). We can also use the void operator, ~ operator, ! operator... …

For example:

!function(){   
  alert("另类的匿名函数自执行");   
}();

Anonymous functions and closures

The English word for closure is closure, which is a very important part of knowledge in JavaScript, because using closures can greatly reduce the amount of our code and make our The code looks clearer, etc. In short, the function is very powerful.

The meaning of closure: To put it bluntly, closure is the nesting of functions. The inner function can use all the variables of the outer function, even if the outer function has been executed (this involves JavaScript scope chain).

function checkClosure(){  
    var str = 'rain-man';  
    setTimeout(  
        function(){ alert(str); } //这是一个匿名函数  
    , 2000);  
}  
checkClosure();

This example looks very simple. There are still many knowledge points after careful analysis of its execution process: the execution of the checkClosure function is instantaneous (maybe it only takes 0.00001 milliseconds), and a variable str is created in the function body of checkClosure. , str is not released after checkClosure is executed, because the anonymous function in setTimeout has a reference to str. After 2 seconds, the anonymous function in the function body is executed, and str is released.

Use closures to optimize code:

function forTimeout(x, y){  
    alert(x + y);  
}  
function delay(x , y  , time){  
    setTimeout('forTimeout(' +  x + ',' +  y + ')' , time);      
}  
/**  
 * 上面的delay函数十分难以阅读,也不容易编写,但如果使用闭包就可以让代码更加清晰  
 * function delay(x , y , time){  
 *     setTimeout(  
 *         function(){  
 *             forTimeout(x , y)   
 *         }            
 *     , time);     
 * }  
 */

The biggest use of anonymous functions is to create closures (this is one of the features 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;  
})();

In this code, the functions addEvent and removeEvent are local variables, but we can use it through the global variable oEvent, which greatly reduces the use of global variables and enhances the security of the web page. We want to use this code: oEvent.addEvent(document.getElementById('box'), 'click', function(){});

var rainman = (function(x , y){  
    return x + y;  
})(2 , 3);  
/**  
 * 也可以写成下面的形式,因为第一个括号只是帮助我们阅读,但是不推荐使用下面这种书写格式。  
 * var rainman = function(x , y){  
 *    return x + y;  
 * }(2 , 3);

Here we create a variable rainman and call the anonymous function directly Initialized to 5, this little trick is sometimes very 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 accessible from the outside. But here we created the inner function, which can access the variable one; and the global variable outer refers to inner, so calling outer three times will pop up the incremental result.

Note

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

/**  
 * <body>  
 * <ul>  
 *     <li>one</li>  
 *     <li>two</li>  
 *     <li>three</li>  
 *     <li>one</li>  
 * </ul>  
 */
     
var lists = document.getElementsByTagName(&#39;li&#39;);  
for(var i = 0 , len = lists.length ; i < len ; i++){  
    lists[ i ].onmouseover = function(){  
        alert(i);      
    };  
}

You will find that when the mouse moves over each

  • element, it always pops up 4, instead of the element subscript we were expecting. Why is this? It’s already mentioned in the notes (final value). Obviously this explanation is too simple. When the mouseover event calls the listening function, it first searches inside the anonymous function (function(){ alert(i); }) to see if i is defined. The result is that it is not defined; therefore, it will search upwards. The result is that it has been defined, and the value of i is 4 (the i value after the loop); therefore, in the end, 4 pops up every time.

    Solution one:

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

    Solution two:

    var lists = document.getElementsByTagName(&#39;li&#39;);  
    for(var i = 0, len = lists.length; i < len; i++){  
        lists[ i ].$$index = i;    //通过在Dom元素上绑定$$index属性记录下标  
        lists[ i ].onmouseover = function(){  
            alert(this.$$index);      
        };  
    }

    Solution three:

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

    2 Memory leak

    Using closures can easily cause memory leaks in the browser. In serious cases, the browser will hang.


  • Statement:
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn