How Does An Anonymous Function in Javascript Work?: Taken From
How Does An Anonymous Function in Javascript Work?: Taken From
Hello JS experts!
I'm reading some posts about closures and see this stuff all over the places, but there is no
explanation how does it works - just every time I'm told to use it...:
Ok I see that we will create new anonymous function and then execute it. So after that this simple
code should work (and it does):
(function (msg){alert(msg)})('SO');
My question is what kind of magic come to place here? I thought that when I wrote:
(function (msg){alert(msg)})
then new unnamed function will be created like function ""(msg) ...
but then why this does not work?
(function (msg){alert(msg)});
('SO');
EDIT:
If you look at ECMA script specification (http://www.ecma-international.org/publications/files/ECMA-
ST/ECMA-262.pdf), there are 3 ways you can define a function. (Page 83, Section 13 Function
Definition)
3. Function Expression
var sum = function(a, b) { return a + b; }
So you may ask, what's the difference between declaration and expression?
From ECMA Script specification:
FunctionDeclaration : function Identifier ( FormalParameterListopt ){ FunctionBody }
FunctionExpression : function Identifieropt ( FormalParameterListopt ){ FunctionBody }
If you notice, 'identifier' is optional for function expression. And when you don't give an identifier,
you create an anonymous function. It doesn't mean that you can't specify an identifier.
Important point to note is that you can use 'mySum' only inside the mySum function body, not
outside. See following example:
Compare this to
function(msg) { alert(msg); }
You created a function expression. And you can execute this function expression by wrapping it inside
parenthesis.
function foo(msg){
alert(msg);
}
foo("Hi!");
foo("Hi!");
(function(msg){
alert(msg);
})("Hi!");
function make_foo() {
return function(msg){ alert(msg) };
}
(make_foo())("Hi!");
It's worth nothing that any variables defined with "var" in the body of make_foo will be closed over
by each function returned by make_foo. This is a closure, and it means that the any change made to
the value by one function will be visible by another.
This lets you encapsulate information, if you desire:
function make_greeter(msg){
return function() { alert(msg) };
}
hello();
It's just how nearly every programming language but Java works.
(function (msg){alert(msg)});
('SO');
consist of two statements. The first is an expression which yields a function object (which will then be
garbage collected because it is not saved). The second is an expression which yields a string. To apply
the function to the string, you either need to pass the string as an argument to the function when it is
created (which you also show above), or you will need to actually store the function in a variable, so
that you can apply it at a later time, at your leisure. Like so:
Note that by storing an anonymous function (a lambda function) in a variable, your are effectively
giving it a name. Hence you may just as well define a regular function:
function(){ alert("plop"); }
2;
So we have to store them in a variable to be able to use them, just like any other value:
You can also use a syntatic sugar to bind the function to a variable:
But if naming them is not required and would lead to more confusion and less readability, you could
just use them right away.
Here, my function and my numbers are not bound to a variable but still can be used.
Said like this, it looks like self-invoking function have no real value. But you have to keep in mind that
JavaScript scope delimiter is the function and not the block ({}).
So a self-invoking function actually has the same meaning as a C++, C# or Java block. Which means
that variable created inside will not "leak" outside the scope. This is very useful in JavaScript in order
not to pollute the global scope.
alert(
{foo: "I am foo", bar: "I am bar"}.foo
); // alerts "I am foo"
Related to functions. As they are objects, which inherit from Function.prototype, we can do things
like:
Function.prototype.foo = function () {
return function () {
alert("foo");
};
};
And you know, we don't even have to surround functions with parenthesis in order to execute them.
Anyway, as long as we try to assign the result to a variable.
One other thing you may do with functions, as soon as you declare them, is to invoke the new
operator over them and obtain an object. The following are equivalent:
var obj = {
foo : "bar"
};