The problem with
this is how it magically gets set. Unlike Python’s
self that is explicitly passed into an object method, the value of
this is based on how the function it is contained within is called.
This highlights how
this is different than
self in Python.
this means the global context. Inside of a browser, this is the
window context, but similar idea.
It may be helpful to think about these three different contexts by considering what is calling the function. To call the
.cleese() method, you write
john.cleese(). Calling the
print() function is actually a short form for calling
window.print() in a browser.
Within that method, the context of
this is the
fruit object itself. So far, this is the same as the
john object on the previous slide, but here’s where it gets a little messier. Within the
.show() method, I want to iterate through the different fruit in the
Think back to the “How is it called?” concept I mentioned previously. What is to the left of the calling dot of an anonymous function? It can’t be
fruit because you’re not inside of the calling function on
Anonymous functions end up in the
global context. The resulting consequence is your
this keyword no longer points to the
fruit object. In fact, without taking additional steps, you have no way of getting at the
fruit context here at all.
In fact, it doesn’t use it. Within the context of an arrow function, the
this hasn’t changed. It can be accessed, though. Consider this
.display() method. The first
this is the
fruit object, as this is inside the member function
.display(). The difference between the
.show() method and the
.display() method is how I’m calling the
This time I’m using an arrow function inside of the
.forEach(). As the arrow function doesn’t rebind the
this value, it will still be whatever value it was before, which is the context of
this inside of the
.display() function, which is the
One word of caution, though. The lack of context in an arrow function can be a problem as well as a solution. Consider this last piece of code. By using the shortcut to define the method
.spear(), you aren’t going to get the value of
In fact, at the time, I thought the
this keyword was like
self in Python. A very frustrating afternoon followed by a chat with a friend of mine cleared a bunch of this up. If, like me, your mental model of
this is based on other languages, you can be for some surprises, and not the happy birthday kind but more like the parking ticket kind.
There are other solutions to the context problem than just the arrow function. A common workaround is to store the value of
this in another variable—a common name for it is
that—within the scope of nested anonymous functions.
The value of
that will still be available in the original object. Some functions, like
.forEach() on arrays, take a parameter that allows you to set the context. When using
.forEach(), you can pass in the current context of
.forEach() will set that context inside of the anonymous function.
.apply(). Use the name of the function you were going to call and then call
.apply() on that function name instead.
You can pass in context and arguments for the named function. The
.call() built-in is exactly like the
.apply() built-in, but instead of taking an array of arguments it uses multi-argument syntax.
And finally, the
.bind() built-in takes the named function, binds the given context, and returns a new function. You can then call the new function from anywhere, and this will be set appropriately wherever you are.
.bind() is pretty powerful, but it can make for some hard-to-trace code.
.bind() happens in a different file or hundreds of lines above, it is easy to forget that the context has been changed and not correctly understand the value of
this when you’re reading the code.
07:40 Everything on this slide feels kind of hackish now that arrow functions exist, and I don’t mean hackish in the “I’m proud of the workaround I’ve found, isn’t this cool?” More of the “I’m ashamed it has come to this,” kind of fashion.
Become a Member to join the conversation.