In-depth understanding of JavaScript Series (4): function expression called immediately

Source: Internet
Author: User

Foreword When you learn JavaScript, often encounter self-executing anonymous function code, today we mainly think about the self-implementation. Before learning more about this, let's talk about the "self-implementation" of the term, this article is not necessarily the name of the function is not entirely right, mainly to see how the individual understand, because some people say immediately call, some people say automatic execution, so you can completely follow your own understanding to take a name, but I hear a lot of people call it "Self-executing", but the author says a lot later to persuade everyone to call it "function expression called immediately." This article is in the original English address: http://benalman.com/news/2010/11/immediately-invoked-function-expression/What is self-executing? In JavaScript, any function creates an execution context when it executes, because the variables and function declared for a function are likely to be within that function only, in which context, when calling function, Provides a simple way to create free variables or Private Sub-function. //since another function is returned in this function, the function can access the free variable i//all say that this internal function actually has permission to invoke an internal object. functionMakecounter () {//I can only be accessed within the Makecounter    vari = 0; return function() {Console.log (++i); };}//Note that counter and counter2 are different instances, each of which has its own range of I. varCounter =makecounter (); counter ();//logs:1Counter ();//Logs:2varCounter2 =Makecounter (); Counter2 ();//logs:1Counter2 ();//Logs:2alert (i);//Reference Error: I do not have defind (because I is present inside makecounter). In many cases, we do not need to makecounter multiple instances, or even some cases, we do not need to display the return value, OK, look down. The core of the problem when you declare something like function foo () {} or var foo=function() {} function, you can implement self-execution by adding parentheses in the back, such as Foo (), see the code://because I think the function of the first declaration below can be appended with a parenthesis () to execute itself, such as Foo (),//because Foo is just a reference to the function () {/* code */}-This expression varFoo =function(){/*Code*/ } // ... Does that mean that the parentheses can be executed automatically after the next one?  function(){/*Code*/}();//syntaxerror:unexpected Token (//The code above, if even run, the 2nd code error, because when the parser resolves the global function or function internal function keyword, the default is to consider a function declaration, not a function expression, If you do not show the compiler, it is declared as a function with a missing name by default, and a syntax error message is thrown because a function declaration requires a name. Narrator: Function (function), brackets (paren), syntax errors (syntaxerror) Interestingly, even if you add a name to the wrong code above, he will also prompt for grammatical errors, except for the reasons above. After an expression with parentheses (), the expression executes immediately, but after a statement with parentheses (), it is completely different, and his only grouping operator. //The following function is syntactically fine, but it's still just a statement//parentheses () will still cause an error, because the grouping operator needs to include an expression functionFoo () {/*Code*/}();//syntaxerror:unexpected token) //But if you pass an expression in parentheses (), there will be no exception thrown//but the Foo function will still not executefunctionFoo () {/*Code*/} (1 ); //because it is completely equivalent to the following code, a function declaration followed by a declaration of an unrelated expression:functionFoo () {/*Code*/ } ( 1); You can access the ECMA-262-3inchDetail. Chapter 5. Functions for further information. Self-executing function expressions to solve the above problem, it's very simple, we just need to enclose the code in parentheses, because the parentheses () in JavaScript cannot contain statements, so at this point, when the parser parses the function keyword, The corresponding code is parsed into a function expression, not a function declaration. //The following 2 brackets () will be executed immediately(function() {/*Code*/} ());//recommended use of this(function() {/*Code*/})();//but this can be used, too.//due to the && of brackets () and JS, the XOR, comma, and other operators are ambiguous on function expressions and function declarations .//so once the parser knows that one of them is already an expression, the others are the expressions by default.//However, please note that the following section explainsvari =function() {return10; } ();true&&function() {/*Code*/ } ();0,function() {/*Code*/ } ();//If you don't care about the return value, or are not afraid to read//you can even add a unary action symbol in front of the function!function() {/*Code*/ } ();~function() {/*Code*/ } ();-function() {/*Code*/ } ();+function() {/*Code*/ } ();//In another case, using the New keyword can also be used, but I'm not sure how efficient it is//http://twitter.com/kuvos/status/18209252090847232New function() {/*Code*/ }New function() {/*Code*/} ()//If you need to pass parameters, just add parentheses ()The above-mentioned parenthesis is to eliminate ambiguity, in fact, there is no need, because the parentheses originally expected is the function expression, but we still use it, mainly for the convenience of developers to read, when you let these automatically executed expressions assigned to a variable, we see the beginning of parentheses (, It will soon be clear, without the need to pull the code to the end to see if there is any parentheses. The self-executing function expression can also be passed as a parameter when the closure is stored and the normal function executes, since the closure can refer to these parameters directly, and the self-executing function expression can save the state effectively by using these locked arguments. //This code is wrong, because the variable i has never been back locked live//instead, when the loop is executed, I get the value when we click//because this time I do really get the value//So whether you click on that connection, the final display is I am link #10 (if there are 10 a elements)varElems = document.getElementsByTagName (' A '); for(vari = 0; i < elems.length; i++) {Elems[i].addeventlistener (' Click ',function(e) {e.preventdefault (); Alert (' I am Link # ' +i); }, ' False ');}//This is available because he is inside the self-executing function expression closure//The value of I is present as an index of locked, after the loop execution is completed, although the value of the last I becomes the total number of a elements (for example, ten)//but the Lockedinindex value inside the closure is unchanged, because he's done it.//So when you click Connect, the result is correct.varElems = document.getElementsByTagName (' A '); for(vari = 0; i < elems.length; i++) {    (function(Lockedinindex) {Elems[i].addeventlistener (' Click ',function(e) {e.preventdefault (); Alert (' I am Link # ' +Lockedinindex); }, ' False '); }) (i);}//You can also apply a self-executing function expression to a handler function as follows//not outside of the AddEventListener .//but relatively speaking, the above code is more readablevarElems = document.getElementsByTagName (' A '); for(vari = 0; i < elems.length; i++) {Elems[i].addeventlistener (' Click ', (function(lockedinindex) {return function(e) {e.preventdefault (); Alert (' I am Link # ' +Lockedinindex);    }; }) (i),' False ');} In fact, the above 2 examples of the Lockedinindex variable can also be replaced with I, because and the outside I is not a function, so there is no problem, this is also anonymous function+the power of closures. Self-executing anonymous function and immediately executing function expression differences in this post, we have been called self-executing functions, specifically self-executing anonymous functions-executing Anonymousfunction), but the original English author has been advocating the use of immediately called function expressions (immediately-invoked Function Expression) This name, the author also gave a bunch of examples to explain, OK, let's take a look://This is a self-executing function that executes itself within the function, recursivelyfunctionfoo () {foo ();}//This is a self-executing anonymous function because no name is indicated//You must use the Arguments.callee property to perform your ownvarFoo =function() {Arguments.callee ();};//This may also be a self-executing anonymous function, only the Foo flag name refers to itself//If you change foo to something else, you'll get a used-to-self-execute anonymous functionvarFoo =function() {foo ();};//Some people call this a self-executing anonymous function (even if it's not), because it doesn't call itself, it just executes immediately. (function() {/*Code*/ } ());//add an indication name to the function expression to facilitate debug//but it must be named, and the function is no longer anonymous.(functionFoo () {/*Code*/ } ());//immediately called function expressions (Iife) can also be self-executing, but may not be commonly used(function() {Arguments.callee ();} ());(functionfoo () {foo ();} ());//In addition, the following code executes in BlackBerry 5 with an error, because in a named function expression, his name is undefined//Oh, strange(functionfoo () {foo ();} ()); Hopefully here are some examples that can make you understand what is called self-executing and what is called immediate invocation. Note: Arguments.callee in ECMAScript5Strict mode is abandoned, so in this mode, it is not available. The final Narrator: module mode when it comes to this immediately called function expression, I think of the module mode, if you are not familiar with this pattern, let us first look at the code://Create an anonymous function expression that is called immediately//return a variable in which the variable contains what you want to expose//The returned variable will be assigned to counter, not the function itself declared outside.varCounter = (function () {    vari = 0; return{get:function () {            returni; }, set:function(val) {i=Val; }, Increment:function () {            return++i; }    };} ());//counter is an object with multiple attributes, and the above code is actually a way of representing the property.counter.get ();//0Counter.set (3); Counter.increment (); //4Counter.increment ();//5counter.i;//undefined because I is not a property of the returned objectI//Reference Error: I is not defined (because I only exist in closures)For more information about module mode, please visit my previous post: In-depth understanding of the JavaScript series (2): Fully parse module mode. More reading hopefully some of the examples above will give you an idea of the function expression immediately invoked (that is, what we call self-executing functions), and if you want to learn more about the function and module patterns, continue to the sites listed below: ECMA-262-3inchDetail. Chapter 5. Functions. -Dmitry A. Soshnikovfunctions andfunctionScope-Mozilla Developer networknamedfunctionExpressions-Juriy "Kangax" Zaytsev fully parse module mode-Ben Cherry (Uncle Translation finishing) Closures explained withJavaScript-Nick Morgan. Synchronization and recommendation this article has been synchronized to the directory index: in-depth understanding of JavaScript series in-depth understanding of the JavaScript series, including the original, translation, reprint and other types of articles, if it is useful to you, please recommend supporting a, to the power of the uncle writing. 

In-depth understanding of JavaScript Series (4): function expression called immediately

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.