In Object Oriented JS we learned that in JS, everything is an object. Because everything is an object, we came to understand that we could set and access additional properties to functions.
Setting properties to a function and additional methods via the prototype is super awesome … but how do we access them?!??!
We were introduced to the
this keyword. We learned that every function gets this property automatically. So at this point in time, if we were to create a mental model of our function execution context( I am not the only one who does this!… right?!?!), it would look something like this:
It took us a little while to get comfortable with the
this keyword, but once we did we began to realize how useful it is.
this is used inside a function, and will always refer to a single object — the object that invokes (calls) the function where “this” is used.
But life isn’t perfect. Sometimes, we lose our
this reference. When that happens, we end up using confusing hacks to save our reference to
this. Check out this confusing hack from our localStorage exercise:
So why did I need to save a
this reference? Because inside deleteBtn.addEventListener,
this refers to the deleteBtn object. This is unfortunate. Is there a better solution?
call(), apply() and bind() — a new hope
Up until now we have treated functions as objects that are composed of a name (optional, can also be an anonymous function) and the code it executes when it is invoked. But that isn’t the entire truth. As a truth loving person, I must let you know that a function actually looks closer to the following image:
What is this??????? Don’t worry! I will now walk through these 3 similar methods that appear on every function with examples. Rejoice!
The official docs say: The
bind() method creates a new function that, when called, has its
this keyword set to the provided value. (It actually talks about even more stuff, but we’ll leave that for another time :) )
This is extremely powerful. It let’s us explicitly define the value of
this when calling a function. Let’s look at cooooode:
Let’s break it down. When we use the
- the JS engine is creating a new
pokemonNameinstance and binding
thisvariable. It is important to understand that it copies the pokemonName function.
- After creating a copy of the
pokemonNamefunction it is able to call
logPokemon(), although it wasn’t on the pokemon object initially. It will now recognizes its properties (Pika and Chu) and its methods.
And the cool thing is, after we bind() a value we can use the function just like it was any other normal function. We could even update the function to accept parameters, and pass them like so:
The official docs for call() say: The
call() method calls a function with a given
this value and arguments provided individually.
What that means, is that we can call any function, and explicitly specify what
this should reference within the calling function. Really similar to the
bind() method! This can definitely save us from writing hacky code (even though we are all still hackerzzz).
The main differences between
call() is that the
- Accepts additional parameters as well
- Executes the function it was called upon right away.
call()method does not make a copy of the function it is being called on.
apply() serve the exact same purpose. The only difference between how they work is that call() expects all parameters to be passed in individually, whereas apply() expects an array of all of our parameters. Example:
These built in methods, that exist on every JS function can be very useful. Even if you do not end up using them in your day to day programming, you will still run into it often when reading other peoples code.
If you have any questions, as always, reach out via Instagram ❤