javascriptは直ちに関数を実行します。
5662 ワード
http://benalman.com/news/2010/11/immediately-invoked-function-expression/
Immedial tely-Invoked Function Expression(IIIIIIIIIIIIIIIIIFSE)
Fortunatey,the SyntxError「fix」is simple.The most widely accepted way to tell the parser to expect a function expression is just to wrap in parens,because in JavaScript,parens can’t contantintement.Athentis.142it knows to parse it as a function expression and not a function declaration.
Saving state with closures
Just like when arggments may be passed when functititionarare invoked by their named dentiinininininininininininininininininininininininininininininininininininininininininininininininininininininininininindedededededededentininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininina closure)an Immediately-Invoked Function Expression can be used to"lock in"values and effectively state.
// Because this function returns another function that has access to the
// "private" var i, the returned function is, effectively, "privileged."
function makeCounter() {
// `i` is only accessible inside `makeCounter`.
var i = 0;
return function() {
console.log( ++i );
};
}
// Note that `counter` and `counter2` each have their own scoped `i`.
var counter = makeCounter();
counter(); // logs: 1
counter(); // logs: 2
var counter2 = makeCounter();
counter2(); // logs: 1
counter2(); // logs: 2
i; // ReferenceError: i is not defined (it only exists inside makeCounter)
Immedial tely-Invoked Function Expression(IIIIIIIIIIIIIIIIIFSE)
Fortunatey,the SyntxError「fix」is simple.The most widely accepted way to tell the parser to expect a function expression is just to wrap in parens,because in JavaScript,parens can’t contantintement.Athentis.142it knows to parse it as a function expression and not a function declaration.
// Either of the following two patterns can be used to immediately invoke
// a function expression, utilizing the function's execution context to
// create "privacy."
(function(){ /* code */ }()); // Crockford recommends this one
(function(){ /* code */ })(); // But this one works just as well
// Because the point of the parens or coercing operators is to disambiguate
// between function expressions and function declarations, they can be
// omitted when the parser already expects an expression (but please see the
// "important note" below).
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();
// If you don't care about the return value, or the possibility of making
// your code slightly harder to read, you can save a byte by just prefixing
// the function with a unary operator.
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();
// Here's another variation, from @kuvos - I'm not sure of the performance
// implications, if any, of using the `new` keyword, but it works.
// http://twitter.com/kuvos/status/18209252090847232
new function(){ /* code */ }
new function(){ /* code */ }() // Only need parens if passing arguments
Saving state with closures
Just like when arggments may be passed when functititionarare invoked by their named dentiinininininininininininininininininininininininininininininininininininininininininininininininininininininininininindedededededededentininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininininina closure)an Immediately-Invoked Function Expression can be used to"lock in"values and effectively state.
// This doesn't work like you might think, because the value of `i` never
// gets locked in. Instead, every link, when clicked (well after the loop
// has finished executing), alerts the total number of elements, because
// that's what the value of `i` actually is at that point.
var elems = document.getElementsByTagName( 'a' );
for ( var i = 0; i < elems.length; i++ ) {
elems[ i ].addEventListener( 'click', function(e){
e.preventDefault();
alert( 'I am link #' + i );
}, 'false' );
}
// This works, because inside the IIFE, the value of `i` is locked in as
// `lockedInIndex`. After the loop has finished executing, even though the
// value of `i` is the total number of elements, inside the IIFE the value
// of `lockedInIndex` is whatever the value passed into it (`i`) was when
// the function expression was invoked, so when a link is clicked, the
// correct value is alerted.
var elems = document.getElementsByTagName( 'a' );
for ( var i = 0; i < elems.length; i++ ) {
(function( lockedInIndex ){
elems[ i ].addEventListener( 'click', function(e){
e.preventDefault();
alert( 'I am link #' + lockedInIndex );
}, 'false' );
})( i );
}
// You could also use an IIFE like this, encompassing (and returning) only
// the click handler function, and not the entire `addEventListener`
// assignment. Either way, while both examples lock in the value using an
// IIFE, I find the previous example to be more readable.
var elems = document.getElementsByTagName( 'a' );
for ( var i = 0; i < elems.length; i++ ) {
elems[ i ].addEventListener( 'click', (function( lockedInIndex ){
return function(e){
e.preventDefault();
alert( 'I am link #' + lockedInIndex );
};
})( i ), 'false' );
}