Maria Blair
Maria Blair

Reputation: 319

Returning functions from functions in JavaScript

I'm learning how to return functions from other functions in JavaScript. Here is my code that works:

var passengers = [
    { name: "Jane", ticket: "coach" },
    { name: "Evel", ticket: "firstclass" },
    { name: "John", ticket: "coach" },
    { name: "Bob", ticket: "premium"}
];

function createDrinkOrder(passenger) {
    var orderFunction;
    if (passenger.ticket === 'firstclass') {
        orderFunction = function() {
            console.log(passenger.name + ', would you like wine or cocktail?');
        };
    } else if (passenger.ticket === 'premium') {
        orderFunction = function() {
            console.log(passenger.name + ', would you like some wine?');
        };
    } else {
        orderFunction = function() {
            console.log(passenger.name + ', soda or water?');
        };
    }
    return orderFunction;
}

function serveOnePassenger(passenger) {
    var getDrinkOrderFunction = createDrinkOrder(passenger);
    getDrinkOrderFunction();
    // createDrinkOrder(passenger);
}

// General function to serve passengers:
function servePassengers(passengers) {
    for (var i = 0; i < passengers.length; i++) {
        serveOnePassenger(passengers[i]);
    }
}

servePassengers(passengers);  

My question is about 'serverOnePassenger' function: when I comment out the first 2 lines in this function and uncomment the 3rd line instead, nothing happens in the console anymore. Why do I have to declare a variable and then assign a function to it, and only then call this var in order for this code to work? Thanks!

Upvotes: 4

Views: 741

Answers (5)

Brian Parry
Brian Parry

Reputation: 276

createDrinkOrderis returning a function object. The third line of code calls createDrinkOrder which returns a function, but never calls the returned function. You don't necessarily need assign the value returned by createDrinkOrder to a variable, but you do need to make sure that the function it returns gets called. You could do it like this without using a variable: createDrinkOrder(passenger)();

Upvotes: 1

Pointy
Pointy

Reputation: 413702

Your own question title is basically the answer: you've written the createDrinkOrder() function as something that returns another function. If you make a function but never call it, the function won't do anything.

You don't need a variable involved as in your serveOnePassenger() function. You could create the function and call it with one statement:

  createDrinkOrder(passenger)();

That calls createDrinkOrder() and then immediately uses the returned value as a function.

Upvotes: 3

Brandon Anzaldi
Brandon Anzaldi

Reputation: 7270

You don't. Your problem is that the function you call returns another function, but the function that actually logs the text isn't called. If you call the returned function like this: createDrinkOrder(passenger)(), it will call both functions.

var passengers = [
    { name: "Jane", ticket: "coach" },
    { name: "Evel", ticket: "firstclass" },
    { name: "John", ticket: "coach" },
    { name: "Bob", ticket: "premium"}
];

function createDrinkOrder(passenger) {
    var orderFunction;
    if (passenger.ticket === 'firstclass') {
        orderFunction = function() {
            console.log(passenger.name + ', would you like wine or cocktail?');
        };
    } else if (passenger.ticket === 'premium') {
        orderFunction = function() {
            console.log(passenger.name + ', would you like some wine?');
        };
    } else {
        orderFunction = function() {
            console.log(passenger.name + ', soda or water?');
        };
    }
    return orderFunction;
}

function serveOnePassenger(passenger) {
    // var getDrinkOrderFunction = createDrinkOrder(passenger); // Because this returns an anonymous function
    // getDrinkOrderFunction(); // It must be executed to have the expected result
    createDrinkOrder(passenger)(); // This line both returns the function, and executes it.
}

// General function to serve passengers:
function servePassengers(passengers) {
    for (var i = 0; i < passengers.length; i++) {
        serveOnePassenger(passengers[i]);
    }
}

servePassengers(passengers);  

Upvotes: 3

akuhn
akuhn

Reputation: 27793

You must call both createDrinkOrder and the function that it created, try this

(createDrinkOrder(passenger))();

Let's go through this step by step

  • createDrinkOrder(passenger) calls createDrinkOrder which returns an anonymous function
  • (...)() calls that anonymous function

Upvotes: 5

nibnut
nibnut

Reputation: 3117

Absolutely - because you only get back the function - you never actually call it... Try this instead:

createDrinkOrder(passenger)();

Hope this helps!

Upvotes: 4

Related Questions