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

JavaScript JavaScript and the DOM (Retiring) Responding to User Interaction Functions as Parameters

Confused about passing the say function

The function exec has a parameter, the say function. The say function has one parameter to itself, something. Standing alone, when say is invoked it prints out the argument of something to the console.

When say is passed as an argument to exec, wouldn't it have two parameters? The one originally from say and then the following defined in exec which is named arg.

function say(something) {
  console.log(something);
}

func exec(func, arg) {
  func(arg);
}

For example

exec(say("Hi, there"), arg);

3 Answers

Joel Kraft
STAFF
Joel Kraft
Treehouse Guest Teacher

Hi, Benjamin Hedgepeth

This is a topic that confuses a lot of people, so just know you're not alone :)

The first thing to note is that when you declare a function, like this:

function say(something) {
  console.log(something);
}

You are creating a variable named say, just like you would if you used the var, const or let keyword. This variable say points, or refers, to a function, in the same way a variable can point to a number, boolean or array, for example. (A variable is also known as a reference, because it refers to a value.)

In fact, you could also create the say function like this:

const say = function(something) {
  console.log(something);
};

This has virtually the same result as the declaration above.

The second thing to note is that references can be passed to other variables:

So just as you can do this:

const num = 5;
const otherNum = num; // -> otherNum now holds a reference to 5

You can also do this:

function say(something) {
  console.log(something)
}
const otherSay = say; // -> otherSay now holds a reference to the `say` function
otherSay('hello'); // -> logs "hello"

The third thing to note is that a function does not execute until parens are placed after it:

say('message');

At this point, say runs, and any arguments placed inside the parens are passed in. There's only one line in say, so it runs, printing the value of something, which holds the string 'message', to the console.

So when you see this:

function exec(func, arg) {
  // func is a function
  // arg is a string
}

exec(say, 'message'); // <- Passing the say function into exec, as well as the string 'message'

Here, a reference to say is passed into the function exec, but it's never being called. The function is available inside exec via the func parameter, though. To call it, we could do this:

function exec(func, arg) {
  func(arg);
}

exec(say, 'message'); // -> logs "message" to the console.

Now the function is called, and the string "message" is printed to the console.

In your example:

exec(say("Hi, there"), arg);

say is being called (or executed--or invoked) as it is being passed into exec. The string "Hi, there" will print to the console as say is executed. However, because the say function does not return any value, the func variable will be undefined inside exec, and you will get an error when the JavaScript interpreter tries to invoke undefined as a function.

Does this help?

Joel Kraft

As I asked Andren, is a function reference an inferred phrase, and not one that would not be explicitly stated in MDN for instance? How is it known that a function without parens is a reference without simply typing the function name into the JavaScript console?

Taking the example in MDN:

1) function greeting(name) {
2)    alert('Hello ' + name);
3)  }
4)
5) function processUserInput(callback) {
6)    var name = prompt('Please enter your name.');
7)    callback(name);
8)  }
9)
10)  processUserInput(greeting);

There is a function declaration with the description greeting with one parameter name (Line 1). However, the name parameter is omitted if the greeting function is treated as a callback (Line 10). How is it that a parameter, that is explicitly apart of a function declaration, be not included with the callback? That just blows my mind...how a function can be passed as an argument to another function without "all of its parts" (couldn't think of any other way to phrase that). If I had parts to make something but left a particular item out, that would leave the thing I'm making to break at some point.

What is greeting, as a callback, referring to then if it has no parameter? If I were to say, okay, greeting is a callback. I am referencing this function. If I forgot what the function looked like I would see that it would initially have a parameter, right?

I'm extremely confused. So much so, I feel like I can't progress further in this track without knowing how to work with callback functions. If you could break this down it would be hugely appreciated?

Joel Kraft
Joel Kraft
Treehouse Guest Teacher

Benjamin Hedgepeth, I'm responding to your questions directly, in case it's helpful.

is a function reference an inferred phrase, and not one that would not be explicitly stated in MDN for instance?

A reference is any name you use to work with a value. A value can be a string, number, boolean, or even a function. In the example below, greeting is a reference to the function declared on line 1.

How is it known that a function without parens is a reference without simply typing the function name into the JavaScript console?

I don't understand what you mean here, sorry. A reference to a function is like a reference to any other value, such as a string, or number. The reference points to the value, and lets you use the value in some way. One way to use a function is to put parens after its reference, which will execute the function.

How is it that a parameter, that is explicitly apart of a function declaration, be not included with the callback?

Declaring a function with parameters just means that that function will be "looking for" those values to be passed in when the function is called. If values are not passed in, there will be no error, the arguments will be undefined inside the function body. So greeting expects a string (name) to be passed in, but if nothing is passed in, i.e. greeting(), you'll just get an alert with "Hello undefined". So it is up to the function that invokes the callback to pass in the correct arguments.

What is greeting, as a callback, referring to then if it has no parameter? If I were to say, okay, greeting is a callback. I am referencing this function. If I forgot what the function looked like I would see that it would initially have a parameter, right?

greeting is being passed into processUserInput. Inside processUserInput, the variable callback references the greeting function. It's the same function, but with another name. So that function is being called with a name argument, on line 7. As you say, it is important for a callback function to be invoked with the correct parameters. The easiest way to do that for this example would be to refer to the function declaration itself. (Is that what you're asking here?)

Aakash Srivastav
seal-mask
.a{fill-rule:evenodd;}techdegree
Aakash Srivastav
Full Stack JavaScript Techdegree Student 11,638 Points

Hey Benjamin Hedgepeth. I would recommend you to watch this course on callback function . It will provide you an indepth knowledge of callback function and also help in clearing your doubts.
Yours question is obvious because , when I started the course, I also face the same problem as It was totally new to me . And I ask the same question to me "How writing function without parenthesis gives us the refrence to that function so that later we can call that function?" . But that course helped me a lot. Hope your will clear your doubts very soon.

andren
andren
28,558 Points

No it would not. Arguments are only supplied to a function when you call it, when you pass a function to another function you do not actually call it.

The example you provide is actually not how you pass a function as an argument. The proper example (and what was shown in the video) is this:

exec(say, "Hi, there");

The important difference is that you do not add parenthesis after the function name. In JavaScript if a function is followed by parenthesis it will be called immediately, if you type the name of a function without parentheses then JavaScript will not call the function but will instead just return a reference to said function.

This reference is what is passed into the exec function, and subsequently called within it. So say is not passed any arguments as it is passed in. If you do supply it with arguments as you pass it then you are not passing in a reference but instead calling it and passing in whatever that function returns, which is not what you are meant to do when passing a callback.

I'm still having difficulty understanding this.

Taking the code from the video

function say(something) {
    console.log(something);
}

function exec(func, arg) {
    func(arg);
}

How do you know that only typing the function name without parentheses gives a reference? Is the documentation that refers to this?

From MDN: https://developer.mozilla.org/en-US/docs/Glossary/Callback_function

"A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action."

I understand that the say function is being passed, as input, to the exec function. However, as mentioned above, the inner function, say, is invoked within the outer function. It's my understanding the invoked and called are synonymous terms. So while it's an argument it's still a function being called?

If its being called that would include the something parameter.

Secondly, how is arg being passed to the callback function? Why is this happening? The parameterarg' is forexecnotsay`.

I'm just really confused about this topic.

andren
andren
28,558 Points

How do you know that only typing the function name without parentheses gives a reference?

To be honest I can't remember exactly where I learned this fact as it's been a while since I learned the basics of the JavaScript language, but the fact that referencing a function is done by not including parenthesis is just a fundamental part the JavaScript language.

It's my understanding the invoked and called are synonymous terms. So while it's an argument it's still a function being called?

Invoked and called are indeed synonymous terms, but you are misunderstanding the documentation. In the documentation you link to the term outer function is used to refer to the function the callback is passed into. So when they say the callback is invoked in the outer function they are stating that it is invoked within the function that has the callback passed to it, not that it is invoked as it is being passed in.

Secondly, how is arg being passed to the callback function?

Once you pass an argument into a function it can be referenced within that function like a normal variable, so within exec arg is a variable that contains whatever was passed in. So when arg is used during the call to the callback it just passes in whatever value was stored in said variable. What function the argument was originally for doesn't really matter. Arguments are just a way to pass data into a function, once the data is inside the function it can be used for anything, including passing it directly into a different function.