It's time for a JavaScript aside.
Let's talk for a moment about an important,
fundamental, and incredibly powerful aspect
of the JavaScript programming language
that Node relies upon,
and one that's often misunderstood: first-class functions
and function expressions.
Oh, actually, big word alert.
First-class functions: everything you can do
with other types, like strings or numbers,
you can do with functions.
A lot of major programming languages
do not have this feature.
JavaScript does.
It's incredibly powerful, but it also makes
for some patterns and some appearances in code
that you may not be used to if you're not used to
this in JavaScript or other languages
that have this feature.
But functions in JavaScript are first-class.
You can use them just like you use any other type.
You can even assign them to variables
and put them in arrays.
Again, it makes for some powerful patterns,
and it also allows us to write function expressions.
Big word alert.
An expression: an expression just means a block of code
that results in a value,
like setting a variable equal to a value.
That's an expression.
Function expressions are possible in JavaScript
because functions are first-class.
So when I write a string that results in a value,
when I write an object or a number, it results in a value.
And I can use a function expression
to create a function essentially on the fly.
Alright, let's use Node to run some JavaScript
and see what this looks like.
I have an app.js file open here in Visual Studio Code.
I'll go ahead and write some JavaScript.
We'll start with a function statement.
That's the type of function you're used to most likely.
I'll just call this function greet and say hi.
And then I'll invoke, or call the function with parentheses.
Oh, oops, right, I said invoke the function, big word alert.
Invoke just means run the function,
if you haven't heard that phrase before.
We also say often call the function,
so invoke, call, same thing.
Alright, so this is just a normal,
what's called a function statement.
I've declared a function,
I've created it here, and I've called it.
Let's go run this.
I'll go ahead to my command prompt,
I'll switch to the location where I have this file,
and I'll just type node and then app.js, and it says hi.
So that's a normal function statement.
Now, we said that functions in JavaScript are first-class.
Functions are first-class.
That means we can pass them around
like variables, for one thing.
So let's say I made a different function called logGreeting
and I accept a parameter,
and we'll just call this fn for function.
And then I'm going to invoke the function that I'm given.
Now, that might look a little strange,
but we're going to give this function another function.
This variable here will be a function.
We can do that because functions
in JavaScript are first-class.
And then since a function is past here,
I can invoke that function, I can call it, I can say run.
So I could say logGreeting, and that's a function,
and I'm going to give it a function that it's going to use.
So greet is a function.
Actually, functions in JavaScript are objects,
a special kind of object, and that's why this is possible.
So just like I might pass a string to a function
or a number to a function, I can pass a function.
I can use a function like any other type,
like any other type of variable.
So here I'm saying call the logGreeting function,
and this parameter I'm giving it is greet,
the greet function.
Notice I'm not putting parentheses.
That would actually run the function
and I would be giving it the result.
But rather, I'm actually literally
just giving it the function.
So what's going to happen?
Well, we'll see that fn will be this greet function,
and then it's going to invoke it,
which is essentially doing the same as what's right here.
So we should still see console.log hi being executed.
So now, we should see hi twice, here and here.
So I'll go ahead and run node app.js again,
and there's my two his, get that?
So this one ran, and in this case,
I used the fact that the functions are first-class
to treat this function like any other variable
and pass it around and then use it.
This feels a little strange at first,
but it's incredibly powerful and incredibly useful,
and you'll actually use this concept, this feature a lot
when you're writing Node.js programmes.
Now, let's see what a function expression looks like.
Remember, a function expression is just a special type
of expression, an expression being a block of code
that results in a value.
So this is an expression.
I just made a string.
This is an expression.
I just made a number.
And I can, let's say create a variable, greetMe,
and I can write my function like I would any other value,
as an expression here.
Notice that I wrote the function on the fly.
It's part of this larger statement.
So just like I might have put string here,
I can write a function.
That's a function expression.
This is very powerful, again, for a number of reasons.
But what I have here is a variable
that now has this function, which is actually
a special type of object,
but has this function as its value.
So I can then call it, greetMe , I can invoke it.
This function is anonymous,
meaning I didn't give it a name here like I did here
before the parentheses, but my variable points to it,
so when I run the parentheses, the JavaScript engine knows
to execute this function, to invoke it.
And it's still first-class.
It's first-class, so I could still pass it around.
I could pass greetMe to my logGreeting function.
Notice what I just did.
I used a function expression to create a function,
set a variable equal to that function,
and call the function.
And then I used that same variable
and gave it as a parameter,
which also invokes that same function in this parameter here
in this function.
Alright, so this could be a little confusing.
I encourage you to try it, take a good look.
Give it a try for yourself.
It becomes pretty clear when you stop and look at it.
So I could run this in the Node.js command prompt,
but for clarity's sake, let's go ahead
and step through the code.
So I'm going to go to the debug, I'll hit start, alright.
So my first greet was called, and now I'm console.log hi,
and then it goes to logGreeting, I'm going to step in,
and I see that fn is the greet function.
That's the function that I just passed,
and so it's going to run it,
and it runs the console.log hi.
Then I'm going to create a variable called greetMe
and use a function expression,
And now greetMe is that function expression
that contains that console.log,
so greetMe is now a function and I can invoke it.
And then I'm going to go ahead and pass it to logGreeting.
This time, fn will be that function with no name,
the anonymous function, the one that's set to greetMe,
because that's what I passed to it down here at the bottom,
and I'll invoke it.
And if I go to my console window, I see Hi Tony twice,
down there at the bottom, why?
Because I invoked it here
and then I passed it to logGreeting and invoked it again.
Okay, make sense?
I'm creating functions on the fly and passing them around,
because functions in JavaScript are first-class.
Alright, now in Visual Studio Code,
I could either close this or I could hit stop,
and that stops the code from running
and it stops the debugger.
Now, let's show one more interesting pattern
that you'll see a lot.
I'm going to use a function expression on the fly,
logGreeting, and then instead of passing a variable,
I'm actually going to write the function,
let's say Hello Tony! so we can tell the difference.
Notice I wrote the function expression
as if I was creating it as part
of the invocation of logGreeting.
In other words, I could write an actual string
or a number instead of a variable,
and I can also write a function instead
of setting the function to a variable.
And logGreeting will get this function and execute it.
Again, you'll see this kind of pattern a lot.
Why bother setting this function equal to a variable
if I'm only going to use it once, for example.
So I'll just create the function on the fly
and write it here in JavaScript.
The JavaScript engine allows this kind of syntax.
It's really very convenient.
So if I run this, I'll just go back
and run this here, node app.js.
See that last Hello Tony?
The function was created on the fly, passed to logGreeting,
and logGreeting invoked that function.
So this is the kind of pattern, the kind of things
you can do with first-class functions
and function expressions in JavaScript.
We're going to see this a lot,
so if you're not familiar with this pattern,
or maybe you have seen it and not fully realised
what it was, we're going to use it a lot and see it a lot.
And so we needed to understand this in order to understand
some of the things that we're going to see in this section.
Alright, so that's first-class functions
and function expressions.
Let's move on with the course.