I got this example from page 79 of a book called Object Oriented JavaScript by Stoyan Stefanov. Not really knowing what to do, the first time I ran this program (by hitting enter) it returned 'undefined'. After that, following the author's instructions, I called it a();
and got the alert 'Worky worky'
My questions are
a) Did I do the first step correctly? i.e. am I supposed to run a self-invoking program by merely hitting "enter/return"?
b) if I was correct to just hit "enter/return" to run the program, why did it give a result of "undefined." This program, says the author, refuns a reference (on its first run-through) to the function actualWork() ? if it returns a reference, why is that considered undefined? Is it important somehow?
Note that I tried to enter the code in jsfiddle.net and then hit run and nothing happened, but that I got "undefined" when I ran it the first time in the console and then the alert afterwards when I did a();
var a = function() {
function someSetup(){
var setup = 'done';
}
function actualWork(){
alert('Worky-worky');
}
someSetup();
return actualWork;
}();
a) depending on how your interpreter works, yes, simply running the script (by pressing return) defines function a();
b) it gave "undefined" because the program itself doesn't return anything, but the function a(); does.
the code you quoted above represents a function a(); which, when invoked, should do the following:
- define 2 other (temporary) functions
- run one of them (someSetup)
- return the other one.
so i would use the program by:
- running to define a();
- calling
var x=a();
- (optional) checking if
setup=='done'
- calling
x();
(which was returned by a()) should show the alert.
EDIT
sorry, i didn't see the }(); at the end, so it's not 100% correct. the (); at the end is - as Jon and Tomasz both said - short form for "take the function's return value as a new function and run it immediately".
This code is equivalent to:
var f = function() {
function someSetup(){
var setup = 'done';
}
function actualWork(){
alert('Worky-worky');
}
someSetup();
return actualWork;
};
var a = f();
So: You are creating variable f
and assigning a function to it. Then You assign the result of invoking f()
to a
, which happens to be a function as well (this is done implicitly in the original code). And at the very end you can run a()
, which runs the the function returned by f()
.
"Self-invoking" means that this code has an immediate effect immediately after it is executed by the compiler, even though all the code is inside a function. This happens because the function is immediately invoked (those ()
in the last line).
This is also what would have happened if you wrote just
function someSetup(){
var setup = 'done';
}
function actualWork(){
alert('Worky-worky');
}
someSetup();
return actualWork;
The difference here is that the "self-invoking program" (which is a bad description for what it is, IMHO) allows you to do this without making the names someSetup
and actualWork
visible to the calling code -- this is generally desirable.
With that explained, let's answer your questions:
- The code snippet does not
return
anything itself (even if it assigns to a
something that is returned by a function); therefore your JS IDE reports that its return value is undefined
.
- The reference to function
actualWork
is returned fine (it's the value assigned to a
); you saw that yourself when you successfully called it with a()
.
undefinded
is returned from statements var a = ...
that is OK. Reference is returned by the right side of assigment.
The anonumous function is invoked immediately and returns a reference to the function actualWork
within it. So a
contains this reference and can be invoked by itself. So a();
should give you the alert.