Instructor: In this lecture we will expand
our JavaScript toolbox even more with
the bind, call and apply methods.
So we know that functions are a special kind
of object, right, and such as the array objects
for example, functions also get a couple
of special methods which they inherit from
the function constructor object, right?
So in this lecture we will talk about
the powerful call, apply and bind methods,
and in a nutshell, these methods allow us
to call a function and set the this variable manually.
So let's see a small example here,
and for that I'm gonna create an object,
and in this case it's just a very simple object,
so no fancy function constructors
or inheritance, none of that stuff,
so just john and then the object literal syntax.
So his name is John of course,
and we've done this a lot of times by now.
His age and then his job, which is a teacher,
and now what we also want here is a method,
and that's a method basically for John to present himself,
and we are going to have two styles here.
First a formal style, and then also a friendly style.
So John is basically going to say a sentence
in which he presents himself, and we will also
make this dependent on the time of the day.
So presentation is a function which accepts
the style and the timeOfDay.
Okay, so depending on the style that we chose,
we will have two different sentences.
So if the style is formal, then we console.log something,
and if the style is friendly then we say something else.
So console.log something else.
Okay, in the formal part we are going to say something
like "Good morning ladies and gentlemen,"
so "Good," then the timeOfDay,
"Ladies and gentlemen!"
And now remember, if we want to have this symbol here,
then we need to actually escape it,
so that JavaScript thinks that it's not closing the string,
but that it's really part of the text.
So "I\'m," so and then his name, so I'm John in this case,
then we wanna say how old, so "I\'m,"
or let's actually first say his job,
so "I\'m a" this.job, so I'm a teacher in this case,
"and I\'m," and now the age, "years old."
So a bit confusing, but it makes sense.
So now if the friendly style is chosen,
then we want to start our sentence
with something like "Hey! What's up?"
And then again, "I\'m," and now we can actually copy this,
and I see I'm missing a plus sign here,
so let's copy this, so then close it,
and I also need to use the timeOfDay,
so "Have a nice " plus timeOfDay.
Okay, so first of all let's test this.
So john.presentation with the formal style,
and let's say in the "morning."
Okay, so it looks good, right?
Actually there's only one space here missing,
but the rest is good, so it's just here,
a space, right, and so also here.
Now let's add another object here for someone called Emily.
So the name is Emily, she's 30 years old, 35,
and she is a designer, okay.
Now suppose that we want to use the presentation method
for the Emily object, which does not have
this presentation method, right?
We can use the call method to do this.
So how does this work?
The first argument of the call method
is always to set the this variable, so let's see this.
So we can say, again, john.presentation,
and now we use the call method on this function,
on this method here.
So call, and now as I said, the first argument here
is the this variable, so if we set the this variable
to emily here, right, then the this variable here
and here, and so on, so on, then this will
no longer be John, but it will Emily, right?
And now we can set the other arguments,
so let's this time use the friendly style,
and it's in the afternoon.
So let's check this, and this works!
So now it's Emily and it still works.
So we have the job and her age,
and this is called method borrowing
because we actually borrowed the method from John,
to use it here on the Emily object.
So again, the call method allows us
to set the this variable here in the first argument,
and we set it to "emily" because we wanted
to use John's presentation method,
but setting the this variable to "emily,"
so that we could use John's method on Emily, right?
So that is the call method.
There is a very similar method which is called
the apply method, and the only difference is
that this one accepts the arguments as an array,
so that's only two arguments, first this variable,
and then an array where all the other arguments go.
So it would be something like this,
so john.presentation, and apply in this case,
and emily, and now as I said, the array.
And then in here we would set the other arguments,
friendly and afternoon.
Now this is not gonna work because our method
does not expect to receive an array as the input, right?
So the presentation wants two normal arguments here,
it doesn't expect to receive an array, so this
is not gonna work, but I just wanted to show it to you
because we will actually use this later in our project.
So let's just comment this out here.
All right, and let's now see the bind method.
So we used the call and the apply,
so the bind method is the one that's missing here.
So the bind is very similar to the call method as well,
so it also allows us to set the this variable explicitly.
However, the difference here is
that bind doesn't immediately call the function,
but instead it generates a copy of the function
so that we can store it somewhere.
And that can actually be extremely useful
to create functions with preset arguments.
So let's see how, so let's create a variable
because as I said, the bind method will return a function,
so we have to store it at function somewhere.
So we're gonna use the bind method
to create a function with preset arguments,
because bind allows us to do that.
So we're gonna preset the friendly argument
so that we don't have to input it again and again.
So let's call this function johnFriendly, okay?
John.presentation, and now I'm going to use bind.
And again, the first argument here is to set
the this variable, which in this case doesn't really matter,
so I'm just going to go with john,
okay, and now I say "friendly."
So this is the first argument of the function,
of the presentation function.
So the style, but I will not set the timeOfDay, okay?
This will not be set here at this point,
I will just leave it like this.
So let's now use the johnFriendly function,
because again this method here returns a function,
so the function will get stored
here in the johnFriendly variable.
So johnFriendly, and now there's only
one argument left to be set, right?
Because I already set the other one as friendly,
so I can now say like "morning" here again,
and this is just gonna work as it did before, so let's see.
All right, so "I'm John, a teacher, 26,
"Have a nice morning."
So you see how useful this is right?
So we have a function now which is always for
the friendly version of the presentation method.
So we can now use it for another time of the day,
so johnFriendly again, now let's say in the "night,"
and again everything that changes here now is "night."
So again, bind allows us to preset some arguments here,
and this, what we just did here,
actually has a name, and it's called carrying.
So carrying is just a technique in which we create
a function based on another function,
but with some preset parameters,
so exactly what we did here.
And bind is extremely useful for that.
And we can of course do the same for Emily.
Okay, so let's say var emily and Formal,
so john.presentation and then bind,
and this time the this variable matters again
because we need to use the presentation method on Emily,
so the this variable will become emily,
and now I'm going to preset this argument to formal.
And I can now use it so emilyFormal,
and then "afternoon" for example.
And here we go, "Good afternoon, Emily,
"designer, and 30 years old."
All right, so now we saw some examples
for call, apply and bind.
Once again, these are more like small, toy examples,
but they really help you to understand
what we can do with call, apply and bind,
and we will actually use them in
a real situation in our next project.
But before doing that, I wanna just very quickly
show you a cool real-world example right here.
So let's bring back some of the code that we wrote
in a lecture about passing functions as arguments.
So I have the code up here, let me see,
oh yeah, this is the one that I want,
and this one here as well, okay.
So let's create some space here, and all right.
Okay, and do you remember this one?
So this was the function that we created here
where we then passed a callback function,
which was to calculateAge and calculate
if someone was of full age.
So imagine this like a machine
which accepts a function, and then applies that function
to all of the elements of an array, right?
So back then we had this FullAge function here,
but actually the FullAge varies from country to country,
so it's not always 18 years like we have here.
For example, in Japan, you have to be 20
to be of full age, and in other countries
it's actually something like 16 or 17.
So what we can do is to pass in a second argument
for the age limit, so something like this.
So we pass in a limit, and then instead of having 18 here,
we say that the element in the array
has to be greater or equal to the limit that we defined.
All right, so let's again start by calculating the ages,
so var ages is arrayCalc, then the years array,
and then our callback function calculateAge.
Now the problem with our FullAge function
is that it accepts two arguments,
but our arrayCalc function here
can only use it with one argument.
So here, right, the fn function is always called with only
one argument, which is this element of the array, right?
So what can we do here?
I would say that the best solution
is to pass in our isFullAge function,
but with the limit already preset, right?
And that's what we're gonna do.
Do you remember how to do that?
Exactly, we use the bind method
because bind allows us to create a copy of a function
with a preset argument, which is exactly what we need here.
And we did that before, and so now we're gonna do it again.
So let's create a variable again called "full,"
but this time it's called fullJapan,
because I'm gonna do it for Japan,
because they have this limit of 20 years.
So this is what we did before also,
so arrayCalc, and now we pass in the ages
that we calculated before, and now we cannot simply pass in
the isFullAge, as I explained before, right?
So isFullAge, so we will not just pass
this function like this, but we will use
the bind method on it before passing it,
so now we can preset the argument.
So first the this keyword, don't forget this,
the first thing always has to be the this keyword,
and in this case we don't really care about it,
so we just say this, and then our preset limit which is 20.
Okay and now what will be passed into the arrayCalc function
is not simply going to be the FullAge function,
but a copy of the isFull function
with 20 as the preset argument for the limit.
So let's see if this actually works,
so let's console.log the fullJapan,
and also let's show the ages so that we can see
if this is actually correct, so ages.
Okay, so yes it seems like it's working
because here we have someone which is 18, right,
but our isFullAge function tells us
that this person is not of full age here, right,
and that makes sense because in Japan, you're only
of full age when you're 20, as we specified here.
So this is working, and this is another very useful way
in which we use the bind method,
and this is really a real-world example.
Cool, so now you have yet another tool in your toolbox,
and that toolbox is getting really, really full right?
We are now almost ready to start our big project,
so let's very quickly move on,
and see you in the next lecture.