admin管理员组

文章数量:1296237

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 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;
}();

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 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;
}();
Share Improve this question edited Oct 24, 2012 at 16:44 hippietrail 17k21 gold badges109 silver badges178 bronze badges asked Mar 20, 2011 at 10:48 LeahcimLeahcim 42k61 gold badges203 silver badges343 bronze badges 1
  • The function returns another function which contains the alert. So after calling your outer function, it will resolve to actualWork being set to a. When you then call a, you basically call the actualWork function, i.e. then you get the alert. – pimvdb Commented Mar 20, 2011 at 11:11
Add a ment  | 

5 Answers 5

Reset to default 4

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 piler, 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:

  1. 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.
  2. 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().

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:

  1. define 2 other (temporary) functions
  2. run one of them (someSetup)
  3. return the other one.

so i would use the program by:

  1. running to define a();
  2. calling var x=a();
  3. (optional) checking if setup=='done'
  4. 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".

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.

本文标签: iifeJavaScript selfinvoking functionStack Overflow