SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    45
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Functions rewriting themselves - question

    I've been reading a book Object-Oriented Javascript and am stuck on one of the examples concerning the following function:

    Code JavaScript:
    function a() {
       alert('A!');
       return function() {
          alert('B!');
       };
    }

    Then it says you can take a new function to overwrite the old one:

    Code JavaScript:
    a = a();

    The first time you run the overwrite, it will alert A!, and the second time it will alert B!.

    My question is why won't it alert B! the first time through if it's returning the function that alerts B!?

  2. #2
    SitePoint Guru
    Join Date
    Sep 2006
    Posts
    731
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bekkilyn View Post

    My question is why won't it alert B! the first time through if it's returning the function that alerts B!?
    Returning a reference to a function does not cause execution that function.
    Tab-indentation is a crime against humanity.

  3. #3
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    45
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think that's part of what i'm not understanding. If

    Code JavaScript:
    a = a();

    is not executing a function, then why would it alert anything at all, including A!?

    I think I'm still having trouble with the idea that something that looks like it's just assigning a value to a variable is actually producing a result on a command line.

    To me, it seems like the assignment should produce nothing at all, and then the next time you call the function after the assignment by using just

    Code JavaScript:
    a();

    it would correctly produce B!.

    I'm just not sure why it's calling A! without B! if it seems to be calling some part of the function a() during the assignment.

  4. #4
    SitePoint Guru
    Join Date
    Sep 2006
    Posts
    731
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bekkilyn View Post
    I think that's part of what i'm not understanding. If

    Code JavaScript:
    a = a();

    is not executing a function, then why would it alert anything at all, including A!?
    a = a(); does execute a function, a function that executes the line: alert('A'); then returns a reference to another function.
    Thereafter a refers to a function that executes the line: alert('B').
    Tab-indentation is a crime against humanity.

  5. #5
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    45
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    In the earlier section of the book on "Functions that return functions", typing

    Code JavaScript:
    var newFunc = a();
    newFunc()

    will cause both A! and B! alert boxes to pop up once newFunc() is entered.

    In a later part of the "Rewrite function" section with a different example that has
    Code JavaScript:
    return actualWork;

    the book points out, "Notice that there are no parentheses in the return, because it is returning a function reference, not the result of invoking this function." (actualWork is a function inside a function)

    However, in the original example that I listed, the function return has parentheses, so why is it a reference instead of being invoked by the parent function?

    While it makes sense that just returning a reference to another function wouldn't actually invoke that function, the examples all seem inconsistent to me about whether the return statement is acting as a reference or actually invoking the function.

  6. #6
    SitePoint Addict
    Join Date
    Nov 2008
    Location
    Shropshire, England
    Posts
    274
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    function a() {
       alert('A!');
       return function() {
          alert('B!');
       };
    }
    a = a();

    First time it's called it alert's a and returns the nested or inner function.

    'a' then basically becomes this

    a = function(){alert('B')}

    The original function could be returning the number 2, 'bananas', an Array or in this case a function, in whichever case a is assigned that value or reference.

    RLM

  7. #7
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,526
    Mentioned
    83 Post(s)
    Tagged
    3 Thread(s)
    Quote Originally Posted by bekkilyn View Post
    owever, in the original example that I listed, the function return has parentheses, so why is it a reference instead of being invoked by the parent function?
    Here is the function that is returned.

    Code javascript:
    return function () {
        alert('B!');
    };

    The parenthesis that I believe you are referring to, are those that specify what arguments the function takes. It's a common code practice to leave a deliberate space between the word "function" and the parenthesis, so that you don't easily mistake them for the parenthesis that invoke a function.

    The above code could also be written as:


    Code javascript:
    var b = function () {
        alert('B!');
    };
    return b;

    The function is still not invoked. Only a reference to the function is being returned.

    In order to invoke the function on the return, you would need to add parentheses to the end of the function name that's being returned:

    Code javascript:
    var b = function () {
        alert('B!');
    };
    return b();

    which can then be converted back to the way the first code looked, but with added parenthesis at the end of the function (to invoke it).

    Code javascript:
    return function () {
        alert('B!');
    }();

    Because the original code returns only the function, without invoking it, it is only the uninvoked version of the function that is returned.


    Code javascript:
    return function () {
        alert('B!');
    };

    Is that starting to make a bit more sense?
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  8. #8
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    45
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it is finally starting to sink in. When the function a is first run, it alerts A! and then just assigns the return function that alerts B! to the a function value but does not actually invoke the function. Then when a function is run a second time, a is no longer the original function, but is instead the previously returned function that alerts B!, so now it will alert B!. Until and if a is overwritten again, it will always alert B! from that point forward.

    I may have another question concerning the return values, as there is still something about them that isn't quite clicking for me, but I'm going to think about it for a while longer.

    Thanks so much to all of you for helping me work through this. It's definitely much clearer now than before.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •