this keyword in JavaScript — this in function, method, event, class, arrow functions

Vivek Singh
4 min readJul 8, 2021

--

The JavaScript this keyword refers to the object it belongs to.

Alone, this refers to the global object.

In a function, this refers to the global object.

In a method, this refers to the owner object.

In a function, in strict mode, this is undefined.

In an event, this refers to the element that received the event.

Global Context :

this === window // returns true;

this === globalThis // returns true

Create a variable named ‘key’ globally. Create a simple function named ‘print’

var key = “value”function print() {    console.log(this.key)}print() // outputs "value"

Inside a function :

this refers to a global object inside a function.

Try to execute this program on your console :

var v = “okay”
function make() {
this.v = “bye”;
console.log(v)
}
v = “now”
console.log(v) // outputs “now”

It is because you haven’t called the function make() yet. If you call function make() and then print v . It will output “bye”. this points to the global object inside a function.

var v = “okay”
function make() {
this.v = “bye”;
console.log(v)
}
v = “now”
make()
console.log(v) // outputs “bye”

Calling a function ‘make()’ directly instead of on an object like obj.abc() — treats window as the object being called upon, if a function is called directly. Hence it has access to global objects.

Sometimes, we lose our ‘this’ reference. When that happens, we end up using confusing hacks to save our reference to this

Maintaining this reference in functions:

An example where we lose ‘this’ reference :

var module = {
xx: 42,
getX: function() {
return this.xx;
}
};
var unboundGet = module.getX;
console.log(unboundGet()); // outputs undefined

Why ? — Because when you call the function unboundGet(), it gets called upon a global object, and globally there is no variable name xx exists.

Hence we need to find a way to pass ‘this’ reference to these functions. That’s where call(), apply(), and bind() come into picture.

  1. bind()

The bind() method creates a new function which ,when called, has its this keyword set to the provided object. The advantage is that this method can be used later as well, at any other part of the code.

var module = {
x: 42,
getX: function() {
return this.x;
}
};
car boundGet = unboundGet.bind(module); //to bind an object
console.log(boundGet()); // outputs 42

2. call()

The call() method calls a function with a given ‘this’ context and arguments provided individually.

The method is called immediately and it allows to pass more parameters than just the `this` context.

Example :yourFuntion.call(thisReference,’vvk’, mayer’)

3. apply()

call () and apply() are similar. The only difference is that apply() expects all parameters to be in an array apart from the object which acts as ‘this’ context. call() expects all parameters to be passed individually (definitely not as an array)

Example :yourFuntion.apply(thisReference,[‘vvk’, mayer’])

Class context :

class Car {
constructor() {
//Bind sayBye but not sayHi to show the difference
this.sayBye = this.sayBye.bind(this);
}
sayHi() {
console.log(`Hello from ${this.name}`);
}
sayBye() {
console.log(`Bye from ${this.name}`);
}
get name() {
return ‘Ferrari’;
}
}
class Bird {
get name() {
return ‘Tweety’;
}
}
const car = new Car();
const bird = new Bird();
// The value of ‘this’ in methods depends on their caller
car.sayHi(); // Hello from Ferrari
bird.sayHi = car.sayHi;
bird.sayHi(); // Hello from Tweety
// For bound methods, ‘this’ doesn’t depend on the caller
car.sayBye();
bird.sayBye = car.sayBye;
bird.sayBye(); // Bye from Ferrari
Output : Hello from Ferrari
Hello from Tweety
Bye from Ferrari
Bye from Ferrari

You see in the above program, notice the last three statements.
Both car.sayBye() and bird.sayBye() have the same output. This is because inside the constructor you have set ‘this’ context to the ‘sayBye’ method using bind(). Hence even if you call sayBye() on different objects, it would not matter as you have already used bind() and defined the ‘this’ context.

Arrow functions :

In arrow functions, this retains the value of the enclosing lexical context’s this. In global code, it will be set to the global object.

A lexical scope in JavaScript means that a variable defined outside a function can be accessible inside another function defined. But the opposite is not true; the variables defined inside a function will not be accessible outside that function.

var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true
var Actor = {
name: ‘RajiniKanth’,
movies: [‘Kabali’, ‘Sivaji’, ‘Baba’],
showMovies: function() {
console.log(this.name)
this.movies.forEach(function(movie) {
console.log(this.name + “ has acted in “ + movie);
});
}
}
Actor.showMovies();Output : RajiniKanth
has acted in Kabali
has acted in Sivaji
has acted in Baba

The name(defined in bold) is not getting printed inside the forEach loop — because this refers to global object inside the forEach, we need to set this context outside forEach so that the logic can work in the correct manner.

var Actor = {
name: ‘RajiniKanth’,
movies: [‘Kabali’, ‘Sivaji’, ‘Baba’],
showMovies: function() {
console.log(this.name)
var obj = this;
this.movies.forEach(function(movie) {
console.log(obj.name + “ has acted in “ + movie);
});
}
};
Actor.showMovies();Output :RajiniKanth
RajiniKanth has acted in Kabali
RajiniKanth has acted in Sivaji
RajiniKanth has acted in Baba

The same logic works fine using an Arrow function without explicitly setting the `this` context.

var Actor = {
name: ‘RajiniKanth’,
movies: [‘Kabali’, ‘Sivaji’, ‘Baba’],
showMovies: function() {
this.movies.forEach((movie) => {
console.log(this.name + “ has acted in “ + movie);
});
}
};
Output : RajiniKanth has acted in Kabali
RajiniKanth has acted in Sivaji
RajiniKanth has acted in Baba

With arrow functions ‘this’ is bound to the enclosing scope at creation time and cannot be changed. The new operator, bind, call, and apply have no effect on this.

As an object method :

When a function is called as a method of an object, its ‘this’ is set to the object the method is called on.

var test = {
key: 37,
f: function() {
return this.key;
}
};
console.log(test.f()); // 37

As a DOM event handler :

In HTML event handlers, ‘this’ refers to the HTML element that received the event

<button onclick=”this.style.display=’none’”>Click to Remove Me!</button>

If you execute the above statement, and click on the button, the button will be removed.

--

--

Vivek Singh
Vivek Singh

Written by Vivek Singh

Software Developer. I write about Full Stack, NLP and Blockchain. Buy me a coffee - buymeacoffee.com/viveksinless

No responses yet