-1

This is my first stackoverflow post! I am sorry if I botch the protocol on how to post. Let me know if I have :-)

I am working through this exercise in Head First Javascript and I don't know why an alternative won't work.

We iterate through passengers in order to find the type of ticket. Depending on the ticket we will provide a different alert: firstclass or else.

In this exercise, at function createDrinkOrders , we are calling a function (orderFunction) in order to provide alert.

Why does this not work if I DO NOT use the orderFunctions in createDrinkOrders?

I removed the orderFunctions in createDrinkOrders, but it alerts two or three times. If I include the orderFunctions in createDrinkOrders, it alerts 12 times. Why do we need the orderFunctions function here?

I imagine that after the iteration the alert, with or without the orderFunction, would produce the same result, but it doesn't why?

let passengers = [{
    name: "Jane Doloop",
    paid: true,
    ticket: "coach"
  },
  {
    name: "Dr. Evael",
    paid: true,
    ticket: "firstclass"
  },
  {
    name: "Sue Propert",
    paid: false,
    ticket: "firstclass"
  },
  {
    name: "John Funcall",
    paid: true,
    ticket: "coach"
  }
];

function createDrinkOrders(passenger) {
  let orderFunction;
  if (passenger.ticket === "firstclass") {
    orderFunction = function() {
      alert("Would you like a cocktail or wine?")
    }
  } else {
    orderFunction = function() {
      alert("Your choice is cola or nothing!")
    };
  }
  return orderFunction;
};



function serveCustomer(passenger) {
  let getDrinkOrderFunction = createDrinkOrders(passenger);
  getDrinkOrderfunction();
  getDrinkOrderFunction();
  getDrinkOrderFunction();
  getDrinkOrderFunction();



};

function servePassengers(passengers) {
  for (let i = 0; passengers.length; i++) {
    serveCustomer(passengers[i]);
  }
};

servePassengers(passengers);

Now the code without the orderFunction... See createDrinkOrders(passengers).

let passengers =[{name: "Jane Doloop", paid: true, ticket: "coach"},
                 {name: "Dr. Evael", paid: true, ticket: "firstclass"},
                 {name: "Sue Propert", paid: false, ticket: "firstclass"},
                 {name: "John Funcall", paid: true, ticket:"coach"}];

    function createDrinkOrders(passenger){

        if(passenger.ticket === "firstclass"){

            alert("Would you like a cocktail or wine?")

        }else{

            alert("Your choice is cola or nothing!")

        }

    };



    function serveCustomer (passenger){


       getDrinkOrderfunction();
       getDrinkOrderfunction();

       getDrinkOrderfunction();

       getDrinkOrderfunction();



    };

    function servePassengers (passengers){
        for(let i = 0; passengers.length; i++){
            serveCustomer(passengers[i]);
        }
    };

    servePassengers(passengers);
10
  • 1
    That depends wholly on how you 'removed' the order functions. Please provide a sample of that removal, just like you did with the code before it was modified. Commented May 25, 2019 at 19:13
  • Hello! I updated the original code. I tested it. It has 16 alerts. Now, without the orderFunction: Commented May 25, 2019 at 19:18
  • I edited it, and put in a new piece of code. Thanks for being patient, I just signed up for stackoverflow and I am still learning the interface. :-) Commented May 25, 2019 at 19:22
  • 1
    The second example will produce an error because getDrinkOrderfunction is undefined. Commented May 25, 2019 at 19:23
  • @Daedalus can you explain a bit, you said it is simple. If I use orderFunction or don't use orderFunction, is the result the same? Is using orderFunction just extra code, or is it necessary? Commented May 25, 2019 at 19:24

2 Answers 2

2

In your second example you are calling createDrinkOrders

let getDrinkOrderfunction = createDrinkOrders(passenger);

and then try to use its return value by assigning it to getDrinkOrderfunction. Have a look at the implementation of createDrinkOrders and you will see that it actually does not return anything. Therefore getDrinkOrderfunction is the value undefined.

The first following call of getDrinkOrderfunction() will fail with an error being thrown.

The original code of createDrinkOrders does not actually execute an alert - instead it returns a proper function to the caller (which function depends on the parameter). If the variable getDrinkOrderfunction contains a function, it can be executed as many times as you want by writing getDrinkOrderfunction(). This will start the actual alert notifications.

Let me explain the last paragraph in more detail by simplifying the code: Let's look at the following alternative implementation of createDrinkOrders:

function createDrinkOrders() {
    let myFunction = function() {
        alert("Hello World");
    };
    return myFunction;
};

What does calling createDrinkOrders(); actually do?

  1. A function is created on the right hand side of the first line; its declaration is split onto multiple lines
  2. That function is assigned to the variable myFunction of the left hand side of the first line
  3. The value of myFunction is returned to the caller; that value is the actual function!

Notice that there is no execution of the inner function which got created during the execution of createDrinkOrders().

How to see that? A function gets executed if you append () after an expression yielding a function. When creating/declaring some value we always my use it immediately or store it in a variable. Just as you may use numbers in variables by just writing a+b you may call a function in a variable myFunction by writing myFunction().

Hopefully we understand now that createDrinkOrders() yields a value which turns out to be a function.

If we write

let foobar = createDrinkOrders();

we now have that value in the variable foobar and it is ready to be called.

foobar(); // call the function stored in foobar
foobar(); // calls it again
Sign up to request clarification or add additional context in comments.

7 Comments

So, I removed let getDrinkOrderfunction = createDrinkOrders(passenger). I see that createDrinkOrders does not create an alert. Can you explain your last paragraph a bit more, its blowing my mind a bit and I can see that the answer to my question is there.
I've added further explanations to my answer.
@HeroWanders in your second code snippet return orderFunction; should be return myFunction;
I think I got ! I made a mental mistake. createDrinkOrderFunction does not iterate at all! It simply packages two functions comfortably based on a condtion (if firstclass or else). Function serve customer handles this and calls it 4 times. The results of the 4 times is dependent upon the function servePassengers--which does the iterating! I hope I got this right :-) Also, how in the hell do you create paragraphs in stackoverflow!?! I hit enter and it submits :-)
@HeroWanders Thanks for that extra detail in your answer! Great help, especially the return part. That clears things up for me a bit!
|
1

Option 1:

function a() {
    let b = c(); //calling c() returns a function that can be called later

    b(); //alert('q') runs here
    b(); //alert('q') runs again here
}

function c() {
    return function() {
        alert('q');
    };
}

Option 2:

function a() {
    let b = c(); //alert('q') runs here

    b(); //throws an error here because b is not defined
    b(); //throws an error here because b is not defined
}

function c() {
    alert('q');
}

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.