Take ‘this’ Quiz, Understand How ‘this’ Works in JavaScript

Image for post
Image for post

Among all the abstract ideas JavaScript has to offer, the ‘this’ keyword can be one of the most challenging concepts to grasp. On the surface, ‘this’ seems like an intuitive keyword that simply refers to the environment (or scope) it resides in.

As you look deeper into the JavaScript runtime, i.e. where the code is being executed, ‘this’ keyword might end up grabbing things you did not expect.

In this post, I created 4 simple scenarios where ‘this’ keyword can be interpreted differently, each followed by a multiple-choice section, a long pause (in case you scrolled too fast and accidentally saw the answer), and the answer with explanations.

Feel free to play around with the code on your console or text editor. Remember, the more and varied situations you encounter, the better you’ll be at identifying and understanding ‘this’ keywords.

Ready? Let’s do this!

Challenge #1

const call = {
caller: "mom",
says: function() {
console.log(`Hey, ${this.caller} just called.`);
}
};
call.says();

What will the code above log to the console?

(A) Hey, undefined just called.
(B) Hey, mom just called.

The answer is…

(B) Hey, mom just called.

Here’s the code block again:

const call = {
caller: "mom",
says: function() {
console.log(`Hey, ${this.caller} just called.`);
}
};
call.says();

Here we have a function declaration inside the call object. As a general rule, ‘this’ is determined by the object invoking a function. Therefore, when the call object invokes says function (call.says()), the ‘this’ keyword inside the says function refers to the call object, making this.caller equal to “mom”.

Pretty straight forward, right?

Challenge #2

const call = {
caller: "mom",
says: () => {
console.log(`Hey, ${this.caller} just called.`);
}
};
call.says();

What will the code above log to the console?

(A) Hey, undefined just called.
(B) Hey, mom just called.

The answer is…

(A) Hey, undefined just called.
(if you’re using a browser console, you might see “null” (Firefox) or “[url referring to the window object]”(Chrome) instead of “undefined”)

Here’s the code block again:

const call = {
caller: "mom",
says: () => {
console.log(`Hey, ${this.caller} just called.`);
}
};
call.says();

Wait, isn’t this code the same as the first one?

If you look closely, the function declaration from Challenge#1 is now replaced by an arrow function.

Arrow functions, as part of ES6 syntax, do NOT have their own ‘this’ keyword. Instead, they will use the ‘this’ keyword of whatever ‘this’ was outside the function when it was created.

In other words, ‘this’ inside the arrow function is not bound to our call object, but instead is already bound to where the call object is being created originally, which in this case is the global object. And because the global object does not know anything about say() function, ‘this’ is undefined.

Challenge #3

const call = {
caller: "mom",
says: function() {
console.log(`Hey, ${this.caller} just called.`);
}
};
let newCall = call.says;newCall();

What will the code above log to the console?

(A) Hey, undefined just called.
(B) Hey, mom just called.

The answer is…

(A) Hey, undefined just called.

What happened? Let’s look at the code again:

const call = {
caller: "mom",
says: function() {
console.log(`Hey, ${this.caller} just called.`);
}
};
let newCall = call.says;newCall();

Here, we assign a new variable to the says function inside the call object. And then we invoke the variable, which is a simple function call.

Notice where we invoke the function. Is it inside the call object? No. We are invoking newCall() function globally, which in turn makes the ‘this’ keyword equal to the global object.

As demonstrated in Challenge#2, since the global object doesn’t know anything about says() function, you get “undefined” as a result.

By now, you might notice a key pattern:
Regular functions change their behaviors BASED ON the object that is CALLING the function.

Challenge #4

function anotherCaller() {
console.log(`${this.caller} called, too!`);
}
const call = {
caller: "mom",
anotherCaller: anotherCaller,
says: function() {
console.log(`Hey, ${this.caller} just called.`);
}
};
let newCall = call.anotherCaller;newCall();

What will the code above log in the console?

(A) mom called, too!
(B) Hey, mom just called.
(C) Undefined called, too!

The answer is…

(C) Undefined called, too!

Again, pay attention to where the function is being invoked:

function anotherCaller() {
console.log(`${this.caller} called, too!`);
}
const call = {
caller: "mom",
anotherCaller: anotherCaller,
says: function() {
console.log(`Hey, ${this.caller} just called.`);
}
};
let newCall = call.anotherCaller;newCall();

We are invoking newCall() function globally, which means the ‘this’ keyword is referring to the global object. It doesn’t matter that we are assigning newCall to a function inside the call object. We are calling newCall globally, and globally is where ‘this’ is assigned.

If you’re feeling adventurous, try declaring anotherCaller() function inside of the call object, like so:

const call = {
caller: "mom",
anotherCaller: function() {
console.log(`${this.caller} called, too!`)
},
says: function() {
console.log(`Hey, ${this.caller} just called.`);
}
};
let newCall = call.anotherCaller;
newCall();

Based on what we just discussed, what do you think the output will be?

Try running the code mentally before checking the answer in your browser. If you got it, you got this (the basics, at least)!

I hope these examples give you a better picture of how ‘this’ keyword works. If you still find it confusing, worry not. As with everything in programming, practice is key.

For more examples, check out the official MDN documentation on ‘this’. I also highly recommend this awesome article. The author provided clear explanations and actually gave me additional insight into some tricky parts in my last challenge.

Fullstack Developer: React with Rails. Currently exploring data structures, D3 visualization, and other front-end magic.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store