Can anybody explain why this works:
var sayHello = function (name) {
alert("Hello there " + name + "!");
}("Mike");
While this does not:
function sayHello (name) {
alert("Hello there " + name + "!");
}("Mike");
Mike Peat
Can anybody explain why this works:
var sayHello = function (name) {
alert("Hello there " + name + "!");
}("Mike");
While this does not:
function sayHello (name) {
alert("Hello there " + name + "!");
}("Mike");
Mike Peat
Edited because my answer had incorrectly read the original post:
As your function is no longer being assigned as a lambda function to a value, invoking the function afterwards with ("Mike") won't work as there's no value to invoke the call on. As others suggested wrapping this with parenthesis to create a temporary variable will still let you invoke the anonymous function:
(function sayHello (name) {
alert("Hello there " + name + "!");
})('Mike');
Your second code is actually:
function sayHello (name) {
alert("Hello there " + name + "!");
}
("Mike");
So you are first declaring function "sayHello", and then you're executing the "statement":
("Mike");
which does nothing.
This will work:
(function sayHello (name) {
alert("Hello there " + name + "!");
})("Mike");
Notice the parens wrapping the function itself. You can also remove the function name "sayHello" and it will still work. As far as why? I'm not positive. Maybe its that by assigning it to a variable and not using the wrapping ()'s, you are actually assigning it to sayHello and then executing on say hello, not the anonymous function.
Surrounding the function definition in ()
before calling it works:
(function sayHello(name) {
alert("Hello there " + name + "!");
})("Mike");
// however --
alert(typeof sayHello); // undefined
So if you want to do something like that - you might as well just make it an anonymous function:
(function(name) {
alert("Hello there " + name + "!");
})("Mike");
And I'm not sure it's required - but for safety - anytime I'm using a closure like that I always wrap it in ()
var sayHello = function (name) {
alert("Hello there " + name + "!");
}("Mike");
This creates an anonymous function and calls it right away with the "Mike" parameter.
Then the return value of that function call is assigned to the variable sayHello
.
function sayHello (name) {
alert("Hello there " + name + "!");
}("Mike");
This just defines a normal function with the name sayHello
and the function statement ends after the closing }.
Then follows the ("Mike") statement which is valid, but does nothing.
All you have to understand here is the difference between FunctionExpressions and FunctionDeclarations in Javascript.
When you surround function with parenthesis -
(function sayHello (name) {
alert("Hello there " + name + "!");
})("Mike");
- you, technically, apply a grouping operator to it. Once applied, overall production is no longer a FunctionDeclarataion, but a FunctionExpression. Compare -
function foo(){ } // FunctionDeclaration
(function foo(){ }); // FunctionExpresson
typeof function(){ }; // FunctionExpression
new function(){ }; // FunctionExpression
FunctionExpression (contrary to FunctionDeclaration), just like any other MemberExpresson can be appended with Arguments ("(" and ")") and will result in function invocation. This is exactly why function is being called in your first example and not in a second.
Note that FunctionExpressions are allowed to have optional Identifiers (contrary to FunctionDeclarations which must always have one), so you can easily omit "sayHello" and end up with so-called anonymous function expression -
(function(){
alert('...');
});
You can check out my article on named function expressions, which delves into subtle details of difference between function expressions and function declarations in much more detail.