_小生_

_小生_正在翻译

Javascript: call(), apply() and bind()

原文链接: medium.com

“this” refresher

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!

bind()

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:

Using the bind() method on line 14.

Let’s break it down. When we use the bind() method:

  1. the JS engine is creating a new pokemonName instance and binding pokemon as its this variable. It is important to understand that it copies the pokemonName function.
  2. After creating a copy of the pokemonName function 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:

call(), apply()

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 bind() and call() is that the call() method:

  1. Accepts additional parameters as well
  2. Executes the function it was called upon right away.
  3. The call() method does not make a copy of the function it is being called on.

call() and 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:

Notice that apply accepts and array, and call expects each param individually.

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