Reputation: 425
I am working through a small exercise from code school and cant figure out why I have to pass the function buildTicket(parkRides, fastPassQueue, wantsRide);
to a variable and then invoke the function on the variable to make this script work.
The code below will not execute (I don't assign the function to a variable):
var parkRides = [
["Birch Bumpers", 40],
["Pines Plunge", 55],
["Cedar Coaster", 20],
["Ferris Wheel", 90]
];
var fastPassQueue = ["Cedar Coaster", "Pines Plunge", "Birch Bumpers", "Pines Plunge"];
var wantsRide = "Birch Bumpers";
function buildTicket(allRides, passRides, pick) {
if(passRides[0]==pick){
var pass = passRides.shift();
return function(){
alert("Quick you have a fast pass to "+pass+"!");
};
} else {
for(var i = 0; i<allRides.length; i++){
if(allRides[i][0] == pick){
return function (){
alert("A ticket is printing for "+pick+"!\n"+
"Your wait time is about "+allRides[i][1]+" minutes.");
};
}
}
}
}
buildTicket(parkRides, fastPassQueue, wantsRide);
But if I add var ticket = buildTicket(parkRides, fastPassQueue, wantsRide); ticket();
it works properly. Full code below:
var parkRides = [
["Birch Bumpers", 40],
["Pines Plunge", 55],
["Cedar Coaster", 20],
["Ferris Wheel", 90]
];
var fastPassQueue = ["Cedar Coaster", "Pines Plunge", "Birch Bumpers", "Pines Plunge"];
var wantsRide = "Birch Bumpers";
function buildTicket(allRides, passRides, pick){
if(passRides[0]==pick) {
var pass = passRides.shift();
return function(){
alert("Quick you have a fast pass to "+pass+"!");
};
} else {
for(var i = 0; i<allRides.length; i++){
if(allRides[i][0] == pick){
return function (){
alert("A ticket is printing for "+pick+"!\n"+
"Your wait time is about "+allRides[i][1]+" minutes.");
};
}
}
}
}
var ticket = buildTicket(parkRides, fastPassQueue, wantsRide);
ticket();
Any insight as to why I need to pass the function to a variable and then call the variable would be greatly appreciated. I am sure I am missing the obvious here.
Upvotes: 1
Views: 85
Reputation: 1343
When you use the variable ticket(); you are doing one more function call than you would do otherwise.
Basically the first buildTicket call by itself... buildTicket(parkRides, fastPassQueue, wantsRide);
looks like...
(function buildTicket(allRides, passRides, pick) {
//... your code here that is returning a function
}(parkRides, fastPassQueue, wantsRide);
under the hood, and will return an anonymous function containing an alert that has not been invoked yet. Looking like...
(function () {
//... your code containing an alert
});
and since it has not been bound to a variable it is just sitting there unable to be invoked because you have no references to it now. There are 2 ways around this problem: 1) you have already figured out which is assigning the anonymous function to a variable and invoking the function using the variable. 2) Is to immediately invoke the returned function by adding another set of parens.
In the end they both do the same thing and will end up giving you the alert via
(function () {
//... your code containing an alert
})();
Also, if all you want is to invoke the alert, you can forget about the extra function statement and the return call and just have
function buildTicket(allRides, passRides, pick){
if(passRides[0]==pick){
var pass = passRides.shift();
alert();
}else {
for(var i = 0; i<allRides.length; i++){
if(allRides[i][0] == pick){
alert();
}
}
}
}
Upvotes: 1
Reputation: 27433
Your buildTicket
function returns a function that does not use a parameter.
For instance, in your code, it returns with a function here:
return function(){alert("Quick you have a fast pass to "+pass+"!");
};
You could invoke the returned function immediately with this syntax:
buildTicket(parkRides, fastPassQueue, wantsRide)();
You could also change the return
lines in function buildTicket
to immediately alert instead of returning a function, but that could break other uses of buildTicket
that expect it to return a function thereby delaying that alert to possibly display at a particular point in the code later when it is needed.
Upvotes: 3
Reputation: 14417
This should work fine!
buildTicket(parkRides, fastPassQueue, wantsRide)();
Upvotes: 2