When I have some code I need to execute more than once I wrap it up in a function so I don\'t have to repeat myself. Sometimes in addition there\'s a need to execute this co
To be called from outside, the function has to be visible from outside. Ideally you would have the self executing function inject it in some passed in context (in this case, this
, which references the global context):
(function(context) {
var foo = function() {
alert('hello');
};
foo();
context.foo = foo;
})(this);
...
foo();
More interesting patterns can be found here.
The second function foo
is a function definition expression.
In a function definition expression, you can only call the function with the name within the function itself according to "Javascript the definitive guide":
For function definition expressions, the name is optional: if present, the name refers to the function object only within the body of the function itself.
It can be used in a recursion function definition expression.
For example:
var f = function factorial(n) {
if (n == 0 || n == 1)
return 1;
else
return n * factorial(n-1);
}
If foo()
is intended to be a global function, i.e., a property of window
, you can do this:
(window.foo = function() {
alert('hello');
})();
// at some later time
foo();
The expression in the first set of parentheses does the assignment to create foo
, but also evaluates to be the function so you can invoke it immediately with ()
on the end.
This pattern works even if the function is supposed to return a value.
If your function doesn't rely on a return value, you can do this...
var foo = (function bar() {
alert('hello');
return bar;
})(); // hello
foo(); // hello
This uses the local reference bar
in the named function expression to return the function to the outer foo
variable.
Or even if it does, you could make the return value conditional...
var foo = (function bar() {
alert('hello');
return foo ? "some other value" : bar;
})(); // hello
alert( foo() ); // hello --- some other value
or just manually assign to the variable instead of returning...
var foo;
(function bar() {
alert('hello');
foo = bar;
})(); // hello
foo(); // hello
As noted by @RobG, some versions of IE will leak the identifier into the enclosing variable scope. That identifier will reference a duplicate of the function you created. To make your NFE IE-safe(r), you can nullify that reference.
bar = null;
Just be aware that the identifier will still shadow an identifier with the same name up the scope chain. Nullifying won't help that, and local variables can not be deleted, so choose the NFE name wisely.