-1

Help me understand these following piece of codes. I'm still newbie in JavaScript.

We know that the following code will run alertbox with A message

// 1
function box() {
  alert('A');
  return function() {
    alert('B');
  }
}
var x = box();

And we know that the following will run alertbox A then followed by alertbox B

// 2
function box() {
  alert('A');
  return function() {
    alert('B');
  }
}
var x = box();
x();

BUT in code below the behavior is just like snippet no 1. I expect it to run ONLY alertbox B.

// 3
function box() {
  alert('A');
  return function() {
    alert('B');
  }
}
var x = box; // no invoking box function
x();

QUESTION: Why did this happen to snippet 3? Didn't we only call x function? From snippet 1 and 2 we know that running x() will trigger alertbox B, but why didn't it appear on snippet 3?

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
xcode
  • 1,637
  • 3
  • 16
  • 25

4 Answers4

3

When you write var x = box; you're storing the function "BOX" on the variable X. You're not executing your box function. To execute, you need to use the parenthesis as box().

Since you have just stored the function and did not run it, when you call x() will yield the same result as calling box().

Simple example

function print(value) {
  alert(value);
}

What happens when you call print('xcode')? - Your browser will alert "XCODE" as you just called the function with that parameter.

Now: var x = print;

Here I am copying the 'print' function over to 'x' variable.

Finally, what happens when you call x('xcode again')? - Your browser will alert "XCODE AGAIN", just like before.

Felipe Skinner
  • 16,246
  • 2
  • 25
  • 30
  • I understand this concept however the main issue is IF 'var x = box(); x()' is equal to run 'A' and 'B' why doesn't 'var x = box; x()' only run 'B' since we are not calling 'B' when declaring 'x' variable. – xcode Apr 23 '16 at 01:33
  • @xcode Because you've called `box` when you write `x()`. `x` is a *reference* to the `box` function. Calling `x` is calling `box` because they reference the same function. – Dave Newton Apr 23 '16 at 01:42
  • You can think of a function as a value... You could do `var box = function() { alert('a') }`. You wouldn't have called it, just stored on `box` variable. Then you need to run it through `box()` afterwards to see the "A" on the screen – Felipe Skinner Apr 23 '16 at 02:04
1

It seems like you are 95% of the way to understanding this, but you got derailed at the end.

You are correct that in the third snippet, we save the function to the variable x:

function box() {
  alert('A');
  return function() {
    alert('B');
  }
}
var x = box; // no invoking box function
x();

But because we did not actually invoke box(), we just store the function in the new variable, var x. So by calling x(), we are essentially just calling box().

The only time that we would get the alert('B') is when the returned value of the box function is saved to a new variable, and then that new variable is called, exactly as we do in snippet 2.

I hope that helps.

1
function box() {
  alert('A');
  return function() {
    alert('B');
  }
}

//fires box() thus firing alert('A');
//returns a function that holds alert('B');
var x = box();

.

function box() {
  alert('A');
  return function() {
    alert('B');
  }
}

//fires box() thus firing alert('A');
//returns a function that holds alert('B');
var x = box();

//fires the returned function alert('B');
x();

.

function box() {
  alert('A');
  return function() {
    alert('B');
  }
}

//sets x EQUAL to box, nothing special nothing happens
var x = box; // no invoking box function

//fires box() thus firing alert('A');
//returns a function that holds alert('B');
x();
Dreamlines
  • 380
  • 4
  • 15
  • So basically in #2 `var x = function() {return alert('B')}` while in #3 `var x = function() {alert('A'); return.........}` am i correct? – xcode Apr 23 '16 at 01:50
  • Bingo. The value of var x in #2 is literally what the return value of the function says: return function() { alert('B') }, while #3 you're just saying x IS box, and then firing x() which is the same as firing box(); You do nothing with the return like you did in #2, where you fired box then fired the return, so it's irrelevant and never fired. – Dreamlines Apr 23 '16 at 01:58
0

It alerts A because you are invoking box.

x is a reference to the function box. When you write x() it's the same as calling box(). It does not alert B because you didn't call the function returned by calling box.

function box() {
  alert('A');
  return function() {
    alert('B');
  }
}
var x = box; // no invoking box function
x()();

This is the same as doing this:

function box() {
  alert('A');
  return function() {
    alert('B');
  }
}

// x1 is a reference to the function box, which alerts, and returns a function
var x1 = box;

// x2 is now the return value of box, the function. A side effect is that
// "A" is alerted.
var x2 = x1();

// Now you're calling the function returned by `box`, which alerts "B".
x2(); // Alerts B
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • So youre implying that `var x = box; x()()` is the same as `var x = box(); x()`? – xcode Apr 23 '16 at 01:36
  • @xcode Same, but different: `x()()` runs both functions with no intermediate steps, while the latter allows you to "save up" the call to the method returned by `box` until you need it. This is called a function generator, e.g., http://stackoverflow.com/a/8537635/438992, http://stackoverflow.com/a/7969111/438992, http://stackoverflow.com/a/8227270/438992. – Dave Newton Apr 23 '16 at 01:41