问题
In javascript, when would you want to use this:
(function(){
//Bunch of code...
})();
over this:
//Bunch of code...
回答1:
Its all about variable scoping. Variables declared in the self executing function are, by default, only available to code within the self executing function. This allows code to be written without concern of how variables are named in other blocks of javascript code.
For example:
(function(){
var foo = 3;
alert(foo);
})();
alert(foo);
This will first alert "3" and then throw an error on the next alert because foo is not defined.
回答2:
Simplistic. So very normal looking, its almost comforting:
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
However. What if I include a really handy javascript library to my page that translates advanced characters into their base level representations?
Wait... what?
I mean. If someone types in a character with some kind of accent on it (such as a french or spanish character) but I only want 'english' characters? A-z in my program? Well... The spanish 'n~' and french 'e/' characters (I've used two characters each for those, but you can probably make the mental leap into the character that represents the accents), those characters can be translated into base characters of 'n' and 'e'.
So someone nice person has written a comprehensive character converter out there that I can include in my site... I include it.
One problem: it has a function in it called 'name' same as my function.
This is what's called collision. We've got two functions declared in the same scope with the same name. We want to avoid this.
So we need to scope our code somehow.
The only way to scope code in javascript is to wrap it in a function:
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
That might solve our problem. Everything is now enclosed and can only be accessed from within our opening and closing braces.
We have a function in a function... which is weird to look at, but totally legal.
Only one problem. Our code doesn't work. Our userName variable is never echoed into the console!
We can solve this issue by adding a call to our function after our existing code block...
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
main();
Or before!
main();
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
A secondary concern: What are the chances that the name 'main' hasn't been used yet? ...so very, very slim.
We need MORE scoping. And some way to automatically execute our main() function.
Now we come to auto-execution functions (or self-executing, self-running, whatever).
((){})();
The syntax is awkward as sin. However, it works.
When you wrap a function definition in parentheses, and include a parameter list (another set or parentheses!) it acts as a function call.
So lets look at our code again, with some self-executing syntax:
(function main() {
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
)();
So, in most tutorials you read, you will now be bombard with the term 'anonymous self-executing' or something similar.
After many years of professional development, I strongly urge you to name every function you write for debugging purposes.
When something goes wrong (and it will), you will be checking the backtrace in your browser. It is always easier to narrow your code issues when the entries in the stack trace have names!
Hugely long-winded and I hope it helps!
回答3:
Self-invocation (also known as auto-invocation) is when a function executes immediately upon its definition. This is a core pattern and serves as the foundation for many other patterns of JavaScript development.
I am a great fan :) of it because:
- It keeps code to a minimum
- It enforces separation of behavior from presentation
- It provides a closure which prevents naming conflicts
Enormously – (Why you should say its good?)
- It’s about defining and executing a function all at once.
- You could have that self-executing function return a value and pass the function as a param to another function.
- It’s good for encapsulation.
- It’s also good for block scoping.
- Yeah, you can enclose all your .js files in a self-executing function and can prevent global namespace pollution. ;)
More here.
回答4:
Namespacing. JavaScript's scopes are function-level.
回答5:
I can't believe none of the answers mention implied globals.
The (function(){})()
construct does not protect against implied globals, which to me is the bigger concern, see http://yuiblog.com/blog/2006/06/01/global-domination/
Basically the function block makes sure all the dependent "global vars" you defined are confined to your program, it does not protect you against defining implicit globals. JSHint or the like can provide recommendations on how to defend against this behavior.
The more concise var App = {}
syntax provides a similar level of protection, and may be wrapped in the function block when on 'public' pages. (see Ember.js or SproutCore for real world examples of libraries that use this construct)
As far as private
properties go, they are kind of overrated unless you are creating a public framework or library, but if you need to implement them, Douglas Crockford has some good ideas.
回答6:
I've read all answers, something very important is missing here, I'll KISS. There are 2 main reasons, why I need Self-Executing Anonymous Functions, or better said "Immediately-Invoked Function Expression (IIFE)":
- Better namespace management (Avoiding Namespace Pollution -> JS Module)
- Closures (Simulating Private Class Members, as known from OOP)
The first one has been explained very well. For the second one, please study following example:
var MyClosureObject = (function (){
var MyName = 'Michael Jackson RIP';
return {
getMyName: function () { return MyName;},
setMyName: function (name) { MyName = name}
}
}());
Attention 1: We are not assigning a function to MyClosureObject
, further more the result of invoking that function. Be aware of ()
in the last line.
Attention 2: What do you additionally have to know about functions in Javascript is that the inner functions get access to the parameters and variables of the functions, they are defined within.
Let us try some experiments:
I can get MyName
using getMyName
and it works:
console.log(MyClosureObject.getMyName());
// Michael Jackson RIP
The following ingenuous approach would not work:
console.log(MyClosureObject.MyName);
// undefined
But I can set an another name and get the expected result:
MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName());
// George Michael RIP
Edit: In the example above MyClosureObject
is designed to be used without the new
prefix, therefore by convention it should not be capitalized.
回答7:
Is there a parameter and the "Bunch of code" returns a function?
var a = function(x) { return function() { document.write(x); } }(something);
Closure. The value of something
gets used by the function assigned to a
. something
could have some varying value (for loop) and every time a has a new function.
回答8:
Scope isolation, maybe. So that the variables inside the function declaration don't pollute the outer namespace.
Of course, on half the JS implementations out there, they will anyway.
回答9:
Here's a solid example of how a self invoking anonymous function could be useful.
for( var i = 0; i < 10; i++ ) {
setTimeout(function(){
console.log(i)
})
}
Output: 10, 10, 10, 10, 10...
for( var i = 0; i < 10; i++ ) {
(function(num){
setTimeout(function(){
console.log(num)
})
})(i)
}
Output: 0, 1, 2, 3, 4...
回答10:
One difference is that the variables that you declare in the function are local, so they goes away when you exit the function and the don't conflict with other variables in other code.
回答11:
Self invoked function in javascript:
A self-invoking expression is invoked (started) automatically, without being called. A self-invoking expression is invoked right after its created. This is basically used for avoiding naming conflict as well as for achieving encapsulation. The variables or declared objects are not accessible outside this function. For avoiding the problems of minimization(filename.min) always use self executed function.
回答12:
Since functions in Javascript are first-class object, by defining it that way, it effectively defines a "class" much like C++ or C#.
That function can define local variables, and have functions within it. The internal functions (effectively instance methods) will have access to the local variables (effectively instance variables), but they will be isolated from the rest of the script.
回答13:
Self executing function are used to manage the scope of a Variable.
The scope of a variable is the region of your program in which it is defined.
A global variable has global scope; it is defined everywhere in your JavaScript code and can be accessed from anywhere within the script, even in your functions. On the other hand, variables declared within a function are defined only within the body of the function. They are local variables, have local scope and can only be accessed within that function. Function parameters also count as local variables and are defined only within the body of the function.
As shown below, you can access the globalvariable variable inside your function and also note that within the body of a function, a local variable takes precedence over a global variable with the same name.
var globalvar = "globalvar"; // this var can be accessed anywhere within the script
function scope() {
alert(globalvar);
localvar = "localvar" //can only be accessed within the function scope
}
scope();
So basically a self executing function allows code to be written without concern of how variables are named in other blocks of javascript code.
回答14:
It looks like this question has been answered all ready, but I'll post my input anyway.
I know when I like to use self-executing functions.
var myObject = {
childObject: new function(){
// bunch of code
},
objVar1: <value>,
objVar2: <value>
}
The function allows me to use some extra code to define the childObjects attributes and properties for cleaner code, such as setting commonly used variables or executing mathematic equations; Oh! or error checking. as opposed to being limited to nested object instantiation syntax of...
object: {
childObject: {
childObject: {<value>, <value>, <value>}
},
objVar1: <value>,
objVar2: <value>
}
Coding in general has a lot of obscure ways of doing a lot of the same things, making you wonder, "Why bother?" But new situations keep popping up where you can no longer rely on basic/core principals alone.
回答15:
(function(){
var foo = {
name: 'bob'
};
console.log(foo.name); // bob
})();
console.log(foo.name); // Reference error
Actually, the above function will be treated as function expression without a name.
The main purpose of wrapping a function with close and open parenthesis is to avoid polluting the global space.
The variables and functions inside the function expression became private (i.e) they will not be available outside of the function.
回答16:
IIRC it allows you to create private properties and methods.
来源:https://stackoverflow.com/questions/592396/what-is-the-purpose-of-a-self-executing-function-in-javascript