Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Greg Schudel
4,090 PointsLost....again...function within a function?
What I'm confused about is the how the second function references the first function?
Secondly, what is the order that the rendering engine is doing within this code??
function say(something){ // I get this
console.log(something);
function exec(func, arg){ // I don't get this, how does this link the two functions together?
func(arg); //what does this do??????????? I don't see any properties or methods present.
}
exec(say, 'Hi, there.');
//how does the 'say' know enough to use the second parameter as an argument within itself? Can someone make equivalent code logic to this while using different key words.
I understand a function can work in a function, I just don't understand how the syntax is telling the Javascript interpreter to do that.
3 Answers
Jennifer Nordell
Treehouse TeacherWow, you've gotten some nice answers here. I'm almost a bit shy about posting mine, but I also made an example although it includes even an extra function. Remember also, that functions (or references to functions) can be passed around in your code just like any other variable. In fact, you can set a variable to reference a function, which is what I did in the second part of this. Take a look and see if it makes sense.
// Say hello to someone
function greetPerson(personsName) {
console.log("Hi there, " + personsName);
}
// That person says hi back.
var sayHiBack = function(personsName) {
console.log("Nice to meet you, " + personsName);
}
function runThis(functionToRun, personsName) {
//the thing passed into functionToRun is a reference to the function
// the personsName will be the argument passed into the appropriate function
functionToRun(personsName);
}
runThis(greetPerson, "Greg Schudel");
runThis(sayHiBack, "Jennifer");
Our last 2 lines here are our function calls. The first one calls the runThis function and passes in the function name, and the person's name. I'm going to kick this off by saying hi to you. So our code goes up and finds the reference to runThis. Inside of runThis we accept the name of the function we want to run and the name of the person. In the first case, we passed in greetPerson, so it then goes up to greetPerson which takes a name of a person. This was passed in as an argument from the functionToRun as personsName. The function then performs the console.log statement with the name of the person sent in.
In the last line, it's much the same. We start by calling the runThis function and then passing in the reference to the function we want run. This time, you're going to say hi back to me so we send in my name. As you'll notice in this case, the sayHiBack is a variable holding a reference to a function. Inside this, We passed my name to the runThis which then passes it along to sayHiBack.
You've gotten some brilliant answers here, but if you have any questions or comments, feel free to ask!
Alexander La Bianca
15,960 PointsWelcome to javascript and the weird things that make javascript awesome. In javascript, functions are first class citizens which means you can pass a function as an argument to another function. Just like you can pass any variable as an argument. That is exactly happening in your example.
function say(something){ //Here we just have a regular function
console.log(something);
}
function exec(func, arg){ //Here we have a more special function - it takes a function as an argument. How do I know that?
func(arg); //I know that because func(arg) is telling me that func must be a function as it is executed here
}
exec(say, 'Hi, there.'); //now here you are executing your exec function. and passing it a function reference. So imagine the inside of your function now looking like:
exec(say, 'Hi, there.') {
say('Hi, there'); //and you know this function from the very top. just a very boring regular function
}
This is a very common pattern in javascript and is what makes up callback functions. I am sure you have seen syntax like this:
button.addEventListener('click',function() {
//do something in here
//the function you pass is a callback function
});
Having this knowledge you can utilize your own functions that take callbacks
function someFunctionWithaCallback(firstName, lastName, callback) {
var fullName = firstName + " " + lastName;
callback(fullName);
}
//Now let's use that callback
someFunctionWithaCallback('Joe', 'Doe', function(theFullName) {
console.log(theFullName); //Joe Doe
});
Understand that concept and you will find javascript a lot more powerful
Greg Schudel
4,090 Pointsfunction someFunctionWithaCallback(firstName, lastName, callback) {// understand this var fullName = firstName + " " + lastName; callback(fullName); // but this doesn't make the fullName a function within a function, does it?
}
and are you creating an instance or a constructor function here?
Alexander La Bianca
15,960 PointsI am not creating an instance function. Its just a regular function.
function someFunctionWithaCallback(firstName, lastName, callback) {// understand this
var fullName = firstName + " " + lastName;
callback(fullName); // fullName is just the variable from above that I pass into the callback function as a parameter
}
//When i now want to execute this regular function by passing in an anonymous function as my callback,
//I know that the parameter to the callback will be the fullName that is created in the inside of the someFunctionWithaCallback
someFunctionWithaCallback(firstName,lastName, function(fullName) {
//do stuff here with the fullName
});
You just need to know that you can treat a function just like a regular variable in javascript. Pass them around and even pass them into functions as parameters like we are doing here
Jonathan Grieve
Treehouse Moderator 91,254 PointsI think what's happening is the exec function is taking 2 arguments. It's kind of like the glue that links the 2 functions together. 1 parameter, is the name of a function, which is the previously defined say function. So that becomes the first value when you call the exec function - that value is the same of the say function.
Then the second argument is the argument for the message. It's where the something keyword comes in.
It wouldn't work if you passed in a direct value to the console.log method, but as it's a reference to a value, you can call it directly with exec.
Greg Schudel
4,090 PointsGreg Schudel
4,090 PointsIt's a bit clearer...couple questions
Jennifer Nordell
Treehouse TeacherJennifer Nordell
Treehouse TeacherFirst, I think you're confusing a callback with a normal function call. The last two lines are function calls. They call a function named
runThis. That function has two parameters. Now you could try to send inrunThis(2, "Jennifer");, but it will fail because the line inside demands that it be a function. There is no way here to send in an anonymous function that I know of. We're specifically tellingrunThiswhich function we want to run. Thus, it must be named.So ok, we send in
greetPerson. Remember, parameters are essentially local variables only defined during the life cycle of that function. What you have now is something akin tofunctionToRun = greetPersonandpersonsName = "Greg Schudel". That linefunctionToRun(personsName);is now equivalent togreetPerson("Greg Schudel");. The function does not reference itself although that can happen and is known as recursion which is a much more advanced topic. The function itself is calledrunThis. If it had referened itself, we'd have a line starting a call torunThis.Finally, the function definitions may be in any order. However, the calls to the functions must come after they are defined. If you put the last two lines at the top, or anywhere between the function definitions it will not work.. But you can put
runThisat the top and totally reorder the definitions without it having any effect.