Explain the encapsulated anonymous function syntax

后端 未结 10 1463
时光说笑
时光说笑 2020-11-21 07:02

Summary

Can you explain the reasoning behind the syntax for encapsulated anonymous functions in JavaScript? Why does this work: (function(){})(); but

相关标签:
10条回答
  • 2020-11-21 07:27

    In javascript, this is called Immediately-Invoked Function Expression (IIFE) .

    In order to make it a function expression you've to:

    1. enclose it using ()

    2. place a void operator before it

    3. assign it to a variable.

    Otherwise it will be treated as function definition and then you won't be able to call/invoke it at the same time by the following way:

     function (arg1) { console.log(arg1) }(); 
    

    The above will give you error. Because you can only invoke a function expression immediately.

    This can be achieved couple of ways: Way 1:

    (function(arg1, arg2){
    //some code
    })(var1, var2);
    

    Way 2:

    (function(arg1, arg2){
    //some code
    }(var1, var2));
    

    Way 3:

    void function(arg1, arg2){
    //some code
    }(var1, var2);
    

    way 4:

      var ll = function (arg1, arg2) {
          console.log(arg1, arg2);
      }(var1, var2);
    

    All above will immediately invoke the function expression.

    0 讨论(0)
  • 2020-11-21 07:28

    They can be used with parameters-arguments like

    var x = 3; 
    var y = 4;
    
    (function(a,b){alert(a + b)})(x,y)
    

    would result as 7

    0 讨论(0)
  • 2020-11-21 07:30

    Even though this is an old question and answer, it discusses a topic that to this day throws many developers for a loop. I can't count the number of JavaScript developer candidates I've interviewed who couldn't tell me the difference between a function declaration and a function expression and who had no clue what an immediately invoked function expression is.

    I'd like to mention, though, one very important thing which is that Premasagar's code snippet wouldn't work even if he had given it a name identifier.

    function someName() {
        alert(2 + 2);
    }();
    

    The reason this wouldn't work is that the JavaScript engine interprets this as a function declaration followed by a completely unrelated grouping operator that contains no expression, and grouping operators must contain an expression. According to JavaScript, the above snippet of code is equivalent to the following one.

    function someName() {
        alert(2 + 2);
    }
    
    ();
    

    Another thing I'd like to point out that may be of some use to some people is that any name identifier you provide for a function expression is pretty much useless in the context of the code except from within the function definition itself.

    var a = function b() {
        // do something
    };
    a(); // works
    b(); // doesn't work
    
    var c = function d() {
        window.setTimeout(d, 1000); // works
    };
    

    Of course, using name identifiers with your function definitions is always helpful when it comes to debugging code, but that's something else entirely... :-)

    0 讨论(0)
  • 2020-11-21 07:31

    Great answers have already being posted. But I want to note that function declarations return an empty completion record:

    14.1.20 - Runtime Semantics: Evaluation

    FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }

    1. Return NormalCompletion(empty).

    This fact is not easy to observe, because most ways of attempting to get the returned value will convert the function declaration to a function expression. However, eval shows it:

    var r = eval("function f(){}");
    console.log(r); // undefined

    Calling an empty completion record makes no sense. That's why function f(){}() can't work. In fact the JS engine does not even attempt to call it, the parentheses are considered part of another statement.

    But if you wrap the function in parentheses, it becomes a function expression:

    var r = eval("(function f(){})");
    console.log(r); // function f(){}

    Function expressions return a function object. And therefore you can call it: (function f(){})().

    0 讨论(0)
提交回复
热议问题