JavaScript ‘this’ in Regular, Arrow functions and Methods — a Short Circuit Example
For those new to JavaScript the concept of this
can take a while to settle in.
A great way to understand how it behaves, is through a simple example of this
in the context of regular functions, ES6 arrow functions and methods within objects.
To start, it is worth noting how outside of any function this
points to what is referred as the global object. Consider this example:
this.robot = "Hal 9000";
Try console.log(this.robot)
what you get? Hall 9000 of course.
MDN Documentation explains how this
can be determined by where and how a function is called. There are nuances in strict mode but we will omit them for brevity of this article. With that in mind, lets consider this function:
function robotName(){ console.log(this.robot)}
Calling robotName() will give you an error? Well not really, it will give you Hall 9000 again. Why? Because in a regular function context, this
defaults to the global object (unless we specify otherwise). Let’s do that:
function robotName() { this.robot = "Astro Boy"; console.log(this.robot)}
// => Astro Boy
So when we call robotName(), what do we get? Astro Boy!
Cool.
Let’s get make things a bit more complex. Consider this:
this.robot = "Hal 9000"; const thisRobots = { robot: "Johnny 5", anotherRobotName: function(robot = "R2D2") { return this.robot; }, details: { robot: "Astro Boy", robotName: function() { return this.robot; }, arrowrobotName: () => this.robot }};
If we call thisRobots.details.robotName()
what do we get Hal 9000, Astro Boy or Johnny 5?
You guessed it right Astro Boy again! robotName()
is in the context of the details object. Now, what if we called thisRobots.details.arrowrobotName()
?
Surprised? Well this is a main distinction of arrow functions vs regular functions is that in arrow functions this
will retain the value of its enclosing context. Since it will be determined by its surrounding scope, in our case, is the global context, so again this will be the territory of Hall 9000. this
in arrow functions is always inherited from their surrounded scope, it doesn’t have scope of its own like regular functions.
We still have one more function to try.
If we call thisRobots.anotherRobotName()
without arguments what do you expect we get? Take a minute to look at the function definition above and make your best guess.
(Unfortunately won’t be Bender. Sad indeed)
Johnny 5!
Why?? Well anotherRobotName()
method is defined inside thisRobots
which is an object.
When we call a method in an object, this
is bound to its surrounding object, in this case thisRobots
object.
Hope this made your understanding of this
a bit better! Some useful resources below to continue your journey.