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:


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

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


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!?

Returning a reference to a function does not cause execution that function.

I think that’s part of what i’m not understanding. If

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

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.

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’).

In the earlier section of the book on “Functions that return functions”, typing


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

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.

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

Here is the function that is returned.


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:


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:


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).


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.


return function () {
    alert('B!');
};

Is that starting to make a bit more sense?

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.