this series as effective JavaScript 's reading notes.
The so-called immediate invocation of the function expression, this translation may not be very accurate, it corresponds to the original English is Immediately invoked Function Expression (iife) . The following also uses Iife to express this concept.
First look at a program:
function Wrapelements (a) {var result = [], I, n;for (i = 0, n = a.length; i < n; i++) {Result[i] = function () {return A[i]; };} return result;} var wrapped = wrapelements ([ten, +, +, +]); var f = wrapped[0];f (); // ?
The purpose of this program is to pass in the wrapelements once for each element of the array in the " Packing " operations, replacing the elements with a function that returns them,
you might think that the final output is the result Ten , but the final result is actually undefined .
The reason to make this intuitive assumption is that function () {return a[i];}; in this code, it is generally assumed that the I is the variable that is used in the current loop I , then the following assignment should be true:
Result[1] = function () {return a[1];};
However, don't forget the important fact that in the assignment statement above, a closure is created first. Referring to its external variable i in this closure , we look back at Item One of the principles we learned about closures, which is that closures store their external variables in the form of references, rather than in the form of values.
So, after the loop is over, I the value should be 5 . Then, when calling wrapped[0]() , it is equivalent to calling:return a[5]. Obviously, this value does not exist, so it returns to undefined.
If you replace the above code with the following:
function Wrapelements (a) {var result = [];for (var i = 0, n = a.length; i < n; i++) {Result[i] = function () {return a[ I]; };} return result;} var wrapped = wrapelements ([ten, +, +, +]); var f = wrapped[0];f (); // ?
can be found that the variable I and the N until for the cycle starts before it starts. So what's the result?
The result is still undefined .
this is because variablehoisting (Item) 's sake. Regardless of where the variable is declared in a function , the definition part of the variable always appears at the beginning of the function .
So, how do you get the program to run the way we expect it to, Iife It comes in handy:
function Wrapelements (a) {var result = [];for (var i = 0, n = a.length; i < n; i++) {(function () {var j = i;result[i] = function () {return a[j];};}) ();} return result;}
in the forLoop, you create aIife, the current loop variableIassigned a value to theJ, and then in the back of thefunctionis returned in theA[j]. This is quite a use of another local variable to record the current value of the external variable for future use. SoIifethe value of it is that it can overcomeJavaScriptThere is no block scope in the language(Block scoping)Disadvantage: Save the current value of an external variable by creating an anonymous closure. It's like having the current value of a variable"Freeze"Live for future use.
Iife another form that will require " Freeze " variable passed as a parameter to the Iife Medium:
function Wrapelements (a) {var result = [];for (var i = 0, n = a.length; i < n; i++) {(function (j) {Result[i] = function () {return a[j];};}) (i);} return result;}
when using Iife , there are two things to note:
- if the foror whileused in the loopIife, then be careful not toIifeincluded in Breakas wellContinuestatement. Because Breakand theContinuecan only be used in the loop, otherwise thrownsyntaxerror:illegal Break Statement.
- if Iife in the use of This or arguments , then their meaning may differ from what you imagined, and in the following Items will be described in.
Summarize:
- Closures store references to external variables, not values
- Use Iife to create a local scope
Effective JavaScript Item 13 creates a local domain using an instant-call function expression (Iife)