149

I'm stuck with this concept of 'Functions that return functions'. I'm referring the book 'Object Oriented Javascript' by Stoyan Stefanov.

Snippet One:

function a() {
  alert("A!");

  function b() {
    alert("B!");
  }

  return b();
}

var s = a();
alert("break");
s();

Output:

A!
B!
break

Snippet Two

function a() {
  
    alert('A!');

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

    return b;
}

var s = a();
alert('break');
s();

Output:

A!
break
B!

Can someone please tell me the difference between returning b and b() in the above snippets?

2
  • 4
    You'll notice the first snippet gives an error on s(); Commented Jul 9, 2018 at 6:53
  • When you return just b your returning the function to be called when you invoke s(); when you return b() your invoking b when you return it Commented Nov 10, 2021 at 22:58

11 Answers 11

155

Assigning a variable to a function (without the parenthesis) copies the reference to the function. Putting the parenthesis at the end of a function name, calls the function, returning the functions return value.

Demo

function a() {
  alert('A');
}
//alerts 'A', returns undefined

function b() {
  alert('B');
  return a;
}
//alerts 'B', returns function a

function c() {
  alert('C');
  return a();
}
//alerts 'C', alerts 'A', returns undefined

alert("Function 'a' returns " + a());
alert("Function 'b' returns " + b());
alert("Function 'c' returns " + c());

In your example, you are also defining functions within a function. Such as:

function d() {
  function e() {
    alert('E');
  }
  return e;
}
d()();
//alerts 'E'

The function is still callable. It still exists. This is used in JavaScript all the time. Functions can be passed around just like other values. Consider the following:

function counter() {
  var count = 0;
  return function() {
    alert(count++);
  }
}
var count = counter();
count();
count();
count();

The function count can keep the variables that were defined outside of it. This is called a closure. It's also used a lot in JavaScript.

4
  • Snippet One: var hero = { name: 'Rafaelo', sayName: function() { return hero.name; }, nayName:hero.sayName } hero.nayName(); Snippet Two: var hero = { name: 'Rafaelo', sayName: function() { return hero.name; }, nayName:this.sayName } hero.nayName(); The first snippet gives me the correct output while the second one does not. Why? Regards. Commented Oct 3, 2011 at 9:47
  • this only means something inside a function body, otherwise it is global. What you are saying for this.sayName is that you want the global variable sayName which does not exist, it is undefined, so is not callable.
    – kzh
    Commented Oct 3, 2011 at 10:16
  • 9
    I was confused by the d()(); at first but then realized that the first () calls d and the second () calls d's return value, which is e.
    – skud
    Commented Mar 13, 2014 at 18:47
  • 3
    Eight years later and this is still relevant ! Commented Feb 4, 2019 at 17:39
54

Returning the function name without () returns a reference to the function, which can be assigned as you've done with var s = a(). s now contains a reference to the function b(), and calling s() is functionally equivalent to calling b().

// Return a reference to the function b().
// In your example, the reference is assigned to var s
return b;

Calling the function with () in a return statement executes the function, and returns whatever value was returned by the function. It is similar to calling var x = b();, but instead of assigning the return value of b() you are returning it from the calling function a(). If the function b() itself does not return a value, the call returns undefined after whatever other work is done by b().

// Execute function b() and return its value
return b();
// If b() has no return value, this is equivalent to calling b(), followed by
// return undefined;
6
  • 2
    Of all the answers, I liked your answer more due to its simplicity. Commented Oct 25, 2013 at 7:50
  • Well put! Very easy to understand this answer. Commented Oct 15, 2018 at 22:32
  • Thanks for validating the bit about if the function doesn't return a value the call returns undefined. I discovered this messing around recently: even if the function returns null explicitly, if you assign the value returned to a variable it will be undefined, not null. I imagine this caused a lot of weird problems in some code bases, because null and undefined are not absolutely equivalent with ===.
    – Benjamin
    Commented Feb 24, 2019 at 8:07
  • I'm a few years too late to this question but I still don't understand b. So when s() is called, it calls a(). But since b is only a reference, it doesn't execute through a() and therefore only a() executes. The function finishes and break is executed BUT now since s() is the same as b(), it jumps back into a() to execute it?
    – Julian
    Commented Dec 31, 2021 at 17:06
  • @Julian I will try to clarify further. Function a() never executes b(). It defines/creates function b() and then returns the function b() as its return value. Initially var s = a(); calls a() and stores its return into variable s; s now holds function b(). The var s alone holds a function that can be executed. s() with () executes the function it holds (which is b().) So back to your question, no s() never calls a(). s() calls b() because the variable s refers directly to function b. Commented Dec 31, 2021 at 19:00
45

return b(); calls the function b(), and returns its result.

return b; returns a reference to the function b, which you can store in a variable to call later.

0
21

Returning b is returning a function object. In Javascript, functions are just objects, like any other object. If you find that not helpful, just replace the word "object" with "thing". You can return any object from a function. You can return a true/false value. An integer (1,2,3,4...). You can return a string. You can return a complex object with multiple properties. And you can return a function. a function is just a thing.

In your case, returning b returns the thing, the thing is a callable function. Returning b() returns the value returned by the callable function.

Consider this code:

function b() {
   return 42;
}

Using the above definition, return b(); returns the value 42. On the other hand return b; returns a function, that itself returns the value of 42. They are two different things.

1
  • Plain English, easy to understand!
    – Jeb50
    Commented May 5, 2022 at 19:10
7

When you return b, it is just a reference to function b, but not being executed at this time.

When you return b(), you're executing the function and returning its result.

Try alerting typeof(s) in your examples. Snippet b will give you 'function'. What will snippet a give you?

5
  • First one gives 'undefined'. Does it mean that return b() is completely useless? Also, in the second snippet, function b is private. How then are we able to access the reference outside the function? Please provide me a link which explains this concept clearly if possible. Thanks! Commented Oct 2, 2011 at 23:32
  • I got the answer to the first one. return 1+2 in function b() and the typeof shows number. Thanks. Commented Oct 2, 2011 at 23:35
  • Glad you figured it out! As for the private function: It's not really private in the second example since you already returned it. In fact, it gets assigned to s. Try return this instead of return b though … You'll be able to do s.b() then ;)
    – vzwick
    Commented Oct 2, 2011 at 23:39
  • I'll try it out for sure. Haven't reached the this concept in Javascript yet. Maybe in a couple of days. Thanks! :) Commented Oct 2, 2011 at 23:54
  • function a(){ alert("A!"); function b(){ alert("B!"); } return b; } var s = a(); delete a; s(); ----end---- Is the concept of reference in Javascript same as in Java? Here I've deleted the function a() and yet a call to s() executes b(). So can i say that s contains a copy of b and is not pointing to b() defined in a() ? Commented Oct 3, 2011 at 8:46
5

Imagine the function as a type, like an int. You can return ints in a function. You can return functions too, they are object of type "function".

Now the syntax problem: because functions returns values, how can you return a function and not it's returning value?

by omitting brackets! Because without brackets, the function won't be executed! So:

return b;

Will return the "function" (imagine it like if you are returning a number), while:

return b();

First executes the function then return the value obtained by executing it, it's a big difference!

4
  • In the second snippet, function b is private. How then are we able to access the reference outside the function? Are there any rules governing the same? Commented Oct 2, 2011 at 23:40
  • Objects in JavaScript (this includes functions) are no longer private if you share them.
    – kzh
    Commented Oct 3, 2011 at 0:13
  • @Cafecorridor: If the private function is returned by something (a public function) or is assigned to a public variable (well, an application-accessible variable), you can easily do yourvariable();, otherwise assign the function returned to a variable and do again yourvariable(); Commented Oct 3, 2011 at 3:56
  • this is the best answer, others bla bla bla Commented Oct 20, 2023 at 21:51
3

Snippet one:

function a() {
  
    alert('A!');

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

    return b(); //return nothing here as b not defined a return value
}

var s = a(); //s got nothing assigned as b() and thus a() return nothing.
alert('break');
s(); // s equals nothing so nothing will be executed, JavaScript interpreter will complain

the statement 'b()' means to execute the function named 'b' which shows a dialog box with text 'B!'

the statement 'return b();' means to execute a function named 'b' and then return what function 'b' return. but 'b' returns nothing, then this statement 'return b()' returns nothing either. If b() return a number, then ‘return b()’ is a number too.

Now ‘s’ is assigned the value of what 'a()' return, which returns 'b()', which is nothing, so 's' is nothing (in JavaScript it’s a thing actually, it's an 'undefined'. So when you ask JavaScript to interpret what data type the 's' is, JavaScript interpreter will tell you 's' is an undefined.) As 's' is an undefined, when you ask JavaScript to execute this statement 's()', you're asking JavaScript to execute a function named as 's', but 's' here is an 'undefined', not a function, so JavaScript will complain, "hey, s is not a function, I don't know how to do with this s", then a "Uncaught TypeError: s is not a function" error message will be shown by JavaScript (tested in Firefox and Chrome)


Snippet Two

function a() {
  
    alert('A!');

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

    return b; //return pointer to function b here
}

var s = a();  //s get the value of pointer to b
alert('break');
s(); // b() function is executed

now, function 'a' returning a pointer/alias to a function named 'b'. so when execute 's=a()', 's' will get a value pointing to b, i.e. 's' is an alias of 'b' now, calling 's' equals calling 'b'. i.e. 's' is a function now. Execute 's()' means to run function 'b' (same as executing 'b()'), a dialog box showing 'B!' will appeared (i.e. running the 'alert('B!'); statement in the function 'b')

2

Create a variable:

var thing1 = undefined;

Declare a Function:

function something1 () {
    return "Hi there, I'm number 1!";
}

Alert the value of thing1 (our first variable):

alert(thing1); // Outputs: "undefined".

Now, if we wanted thing1 to be a reference to the function something1, meaning it would be the same thing as our created function, we would do:

thing1 = something1;

However, if we wanted the return value of the function then we must assign it the return value of the executed function. You execute the function by using parenthesis:

thing1 = something1(); // Value of thing1: "Hi there, I'm number 1!" 
0

Here is a nice example to show how its work in practice:

when you call in with two parameter and returns a result

function sum(x, y) {
if (y !== undefined) {
   return x + y;
  } else {
    return function(y) { return x + y; };
 }
}

console.log(sum(3)(8))

there is also another way using the accessing to the arguments in js:

function sum(x) {
 if (arguments.length == 2) {
    return arguments[0] + arguments[1];
 } else {
   return function(y) { return x + y; };
 }
 }
1
  • sum(3)(8) what this expression called? pipe function? Commented Feb 3, 2022 at 17:42
0

Let's try to understand the "return" concept with two examples with the same output, one without using the "return" concept and the other with the "return" concept, both giving the same outcome.

let myLuckyNumber = 22
function addsToMyLuckyNumber(incrementBy, multiplyBy) {
    myLuckyNumber = (myLuckyNumber + incrementBy) * multiplyBy
}
addsToMyLuckyNumber(5, 2)

console.log(myLuckyNumber)

const myLuckyNumber = 22
function addsToMyLuckyNumber(incrementBy, multiplyBy) {
    return (myLuckyNumber + incrementBy) * multiplyBy
}
myNewLuckyNumber = addsToMyLuckyNumber(5,2)

console.log(myLuckyNumber, myNewLuckyNumber)
In the first snippet, you can see the code

myLuckyNumber = (myLuckyNumber + incrementBy) * multiplyBy

you cannot assign a similar code to the second snippet, since it will not work, so we use "return" concept and assign a new variable.

function addsToMyLuckyNumber(incrementBy, multiplyBy) {
    return (myLuckyNumber + incrementBy) * multiplyBy
}
myNewLuckyNumber = addsToMyLuckyNumber(5,2)
0

return statement: The return statement exits the function and replaces the function call (i.e. where the function was invoked) with the value after it

Note: JavaScript returns undefined by default when a function doesn't return any other value.

so:

function a() {
  alert('A');
}

==

function a() {
  alert('A');
  return undefined;
}

thus:

var s = a() 
== 
var s = undefined

function expression: creating a (named or anonymouse) function and asssigning that function to a variable is known as function expression

Note: you can call function expression directly with () after curly braces before ending with semicolon.

so, in

function a() {

  function b() {
    alert("B!");
  }

  return b(); // returns function b with parenthesis
}
var s = a(); 

==

var s = function b() {

   alert("B!");

} () // function is executed directly and returns undefined automatically

==

var s = undefined;

that's why

alert("break");

s();  // not calling a function expression 
== 
undefined(); // causes error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.