Advance Use of “this” in JavaScript

Ankit Srivastava
5 min readMay 28, 2021
this cover image

Today world is capture by JavaScript and JavaScript is easy to learn but hard to master. With this master journey we will cover some best use case of “this” in JavaScript.

In JavaScript this is the function invocation context.

This funny meme

Let understand this from Mozilla -

A function’s this keyword behaves a little differently in JavaScript compared to other languages. It also has some differences between strict mode and non-strict mode.

The challenge is that this has a complicated behavior. That’s why during a JavaScript coding interview you might be asked how this behaves in certain situations.

The best way to get something clear, required a practice on topic. So we're going to come across 7 best use case of this in JavaScript.

Case 1: Variable vs property

Variable and property can change an according to function declaration. Let explore with example.

const object = {
message: 'Hello, World!',

getMessage() {
const message = 'Hello, Earth!';
return this.message;
}
};
console.log(object.getMessage()) // what come on log ??

Answer -

‘Hello, World!’ is logged to console. Check Ex.

object.getMessage() is a method invoke, that’s why this inside the method, There’s also a variable declaration.

const message = ‘Hello, Earth!’ inside the method.

The variable doesn’t influence anyhow the value of this.message.

Case 2 : Cat name

Great with first question, now check another snippet.

function Pet(name) {
this.name = name;

this.getName = () => this.name;
}

const cat = new Pet('Fluffy');

console.log(cat.getName()); // What comes in log?

const { getName } = cat;
console.log(getName()); // What comes in log?

Answer -

‘Fluffy’ and ‘Fluffy’ are logged to console. Check Ex.

When a function is invoked as a constructor new Pet(‘Fluffy’), this inside the constructor function equals the constructed object.

this.name = name expression inside Pet constructor creates name property on the constructed object.

this.getName = () ⇒ this.name creates a method getName on the constructed object of Pet class. And since the arrow function is used, this inside the arrow function equals to this of the outer scope — the constructor function Pet.

Arrow function change the scope to outer function or global scope.

Invoking cat.getName(), as well as getName(), returns the expression this.name that evaluates to ‘Fluffy’.

Case 3 : Delayed greeting

What if we delay the invoke function.

const object = {
message: 'Hello, World!',

logMessage() {
console.log(this.message); // What comes in log?
}
};

setTimeout(object.logMessage, 1000);

Answer -

After a delay of 1 second, undefined is logged to console. Check Ex.

While setTimeout() function uses the object.logMessage as a callback of around 1 second but still, it invokes object.logMessage as a regular function, rather than a method. And during a regular function invocation this equals the global object, which is window in the case of the browser environment.

So, setTimeout() have a scope of window, and in window there is no variable like message.

That’s why console.log(this.message) logs window.message, which is undefined.

Challenge: Can you change and code snipped and make the console.log(this.message) printed as ‘Hello, World!’.

Case 4 : Artificial method

In below snippet can you call logMessage function so that it logs “Hello, World!”?

const object = {
message: 'Hello, World!'
};

function logMessage() {
console.log(this.message); // What comes in log?
}

Answer — there is 3 way to achieve this console.log. Any of them is correct

Method 1 :

Use of call method — Read more.

// Using func.call() method
logMessage.call(object);

Method 2 :

In use of apply method, we change the scope of logMessage scope to object. Read more.

// Using func.apply() method 
logMessage.apply(object);

Method 3 :

Use of bind method — Read more.

// Creating a bound function 
const boundLogMessage = logMessage.bind(object);
boundLogMessage();

To check the working of all 3 method. Check Ex.

Case 5 : Greeting and farewell way

Ok, If you solve above 4 code snippets then you have good knowledge in JS this, but now let’s check some challenging way to use this.

const object = {
who: 'World',

greet() {
return `Hello, ${this.who}!`;
},

farewell: () => {
return `Goodbye, ${this.who}!`;
}
};

console.log(object.greet()); // What comes in log?
console.log(object.farewell()); // What comes in log?

Anwser -

‘Hello, World!’ and ‘Goodbye, undefined!’ are logged to console.

When calling object.greet(), then method have a scope of main Object object, then greet is a regular function. Thus object.greet() returns ‘Hello, World!’.

But farewell() is an arrow function, so this value inside an arrow function always equals this of the outer scope. The outer scope of farewell() is the window scope, where this is the window object. Thus object.farewell() actually returns ‘Goodbye, ${window.who}!’, which evaluates to ‘Goodbye, undefined!’.

Case 6 :Tricky length

So far so good, can you find the value of length.

var length = 4;
function callback() {
console.log(this.length); // What come in log?
}

const object = {
length: 5,
method(callback) {
callback();
}
};

object.method(callback, 1, 2);

4 is logged to console. Check Ex.

callback() is called using regular function invoke inside method(). Since this function call inside method, but callback definition is done before calling, and only invoking is happening in method(), this.length is evaluated as window.length inside callback() function.

The first statement var length = 4, being in the outermost scope, creates a property length on the window object: window.length becomes 4.

Finally, inside the callback() function this.length evaluates as window.length — 4 being logged to console.

Case 7 : Calling arguments

Final but the toughest one. What logs to console the following code snippet.

var length = 4;
function callback() {
console.log(this.length); // What come in log?
}

const object = {
length: 5,
method() {
arguments[0]();
}
};

object.method(callback, 1, 2);

Anwser :

3 is logged to console. Check Ex.

obj.method(callback, 1, 2) is invoked with 3 arguments:

callback, 1 and 2. 

As result the arguments special variable inside method() is an array-like object of the following structure:

{
0: callback,
1: 1,
2: 2,
length: 3
}

Because arguments[0]() is a method invocation of callback on arguments object, this inside the callback equals arguments. As result this.length inside callback() is same as arguments.length — which is 3.

If you solve any 5 problem of this, then you have a good understanding of this in JavaScript.

Happy coding, and thanks for reading this blog. Do write a comment if you have more about the this in JavaScript.

--

--