25
this keyword in JavaScript
Hey everyone !
I have been recently learning
I have been recently learning
ReactJS
. While learning about class based components I stumbled across the bind
keyword.this.somefunction = this.somefunction.bind(this)
While trying to understand this line of code, I realized that the binding of the methods is not a React specific thing, It is a JavaScript thing .
I also realized that to understand the trio of
call, apply and bind
which basically do similar things, we need to understand the this
keyword in JavaScript.So, today I'd like to discuss about :
this
?this
in global scopethis
within an objectthis
within a functionthis
within classesBy learning about all these things we get to know why we bind methods in ReactJS.
Alright! let's get going.

When we use 'this' in our daily conversations it always has a context attached with it, right? For instance, the sentence "This is my house" can only make sense in two ways when you are inside the house or you point to the house you are talking about.
If in the middle of the street you say "This is my house" it doesn't really make sense, because 'this' isn't really pointing to anything. If you have a picture of your house then regardless of the location you can point to the picture and attach the context to 'this', it will be like 'this house(in the picture) is my house'.
Similarly in JavaScript,
this
keyword will point to something according to the context it is in or we can point it to the thing we want using call, apply and bind . This will make better sense when we see the different contexts this
can be defined in. When we create a JavaScript file, even if there are zero lines of code written in the file a few things are created. One of the things created is the window object. The window object contains different properties and methods including things related to DOM.
When we write the
this
keyword in a global context ( outside any kind of function ), by default it points to the window
object.If we create a variable like this
this.thing = "window thing"
we could access it using
this.thing
as well as window.thing
since this
points to the window object.console.log(this.thing)
// # "window thing"
console.log(window.thing)
// # "window thing"
Before we proceed to the context of a function, we need to understand strict mode.
In simple words, strict mode apply more restrictions and rules to JavaScript. Certain things would be allowed in non-strict mode but throw an error in strict mode.
We can enable strict mode using the statement
"use strict"
in the JS file .From here onwards, things will get a little weird, so stick with me.
function printsomething(){
console.log(this) // Window object
}
printsomething()
When we call
this
in a function in non-strict mode it points to the window or the global object. In strict mode this
is undefined and it looses the context."use strict"
function printsomething(){
console.log(this) // undefined
}
printsomething()
When we call the
this
keyword in an object method, this
points to the object it was defined in. For Example :
this.name = "Some other movie"
const movie = {
name : "Peanut Butter Falcon",
print : function (){
console.log(this.name)
}
}
movie.print()
// OUTPUT
// Peanut Butter Falcon
In the above example, we define a method called
print
within the object movie
. The object movie
has a property called name
.In
print
we call console.log(this.name)
which would basically point to the name
property of the movie
object.It will not print "Some other movie" since the
print
function is in the context of the object movie
.Remember when I told you that the value of
Let us use the same object we used previously to understand this.
this
depends on the way it was called?Let us use the same object we used previously to understand this.
What if we assign the method
print
to another variable called globalprint
?this.name = "Rocky"
const movie = {
name : "Peanut Butter Falcon",
print : function (){
console.log(this.name)
}
}
const globalprint = movie.print
globalprint()
//output : Rocky
Now, the context of
this
has changed to the global context since globalprint
is not a method of the movie
object, it is an independent function as we have seen in the function section, points to the global context in non-strict mode
and is undefined in strict mode
.So, the output would be
"Rocky"
instead of "Peanut Butter Falcon"
.
This also applies to callback functions.
this.name = "Rocky"
const movie = {
name : "Peanut Butter Falcon",
print : function (){
console.log(this.name)
}
}
setTimeout(movie.print , 1000 ); // Output : Rocky
We can try to fake a setTimeout method to look at how this works.
function setTimeout(callback, delay){
//wait for 'delay' milliseconds
callback();
}
setTimeout( movie.print, 1000 );
Internally the setTimeout method assigns the
movie.print
to it's callback argument.callback = movie.print
As we saw before, assigning a method to another variable changes it's context. Thus
it will print "Rocky".
print
will be "undefined" in strict mode
and in non-strict mode
it will print "Rocky".
class theatre {
constructor(person,movie){
this.person = person
this.movie = movie
}
display(){
console.log(`${this.person} is watching ${this.movie}`)
}
}
const peter = new theatre("peter","interstellar")
const jack = new theatre("jack","inception")
jack.display()
//output : peter is watching interstellar
peter.display()
//output : jack is watching inception
Within a class
Here the instances being
this
point to the current instance of the class.Here the instances being
jack
and peter
.However, the class methods like
display
will lose context if passed as a callback function or assigned to another variable like we saw in the functions section.Class expression and methods such as the constructor or any class methods are always executed in
strict mode
.Thus callbacks, instead of taking the global context, will be undefined.
const callback = jack.display
callback() // "this" will be undefined
We will be learning about
bind
method shortly to fix this problem. To give you an idea , bind
will basically glue value of this
to the display function and it will always be called in that context, fixing the problem of the context getting lost.Remember the house analogy I used in the beginning?
We'll now understand the pointing at the picture of the house part, that is basically telling javascript explicitly where you want
We'll now understand the pointing at the picture of the house part, that is basically telling javascript explicitly where you want
this
keyword to point rather than JavaScript assigning it for you.call
method is used to call a function with the this
pointing to a thing of your choice.call(thisArg, arg1, ... , argN)
thisArg
helps the call function to knw on which this
should the function be called.Rest arguments are the arguments passed to the function.
Let's understand the use case with an example.
const movie = {
name : "Peanut Butter Falcon",
print : function (){
console.log(this.name)
}
}
Remember this object?
What if we create two movie objects with different movies?
What if we create two movie objects with different movies?
const movie1 = {
name : "Peanut Butter Falcon",
print : function (){
console.log(this.name)
}
}
const movie2 = {
name : "The imitation game",
print : function (){
console.log(this.name)
}
}
We can see here the
objects, we would have to write the same print function multiple times.
print
function is repeated. If there were more of theseobjects, we would have to write the same print function multiple times.
We could use a
call
method in this case.We would remove the
print
method out of the objects and make it as a separate function .const printThings = function (){
console.log(this.name)
}
const movie1 = {
name : "Peanut Butter Falcon"
}
const movie2 = {
name : "The imitation game"
}
Now, we will use the
call
method on the printThings
function with reference to whichever this
value we wantprintThings.call(movie1) // output : "Peanut Butter Falcon"
printThings.call(movie2) // output : "The imitation game"
printThings.call(movie1)
tells JavaScript that we want the above function's this
to point to movie1 object and similarly for movie2.It is as though the function is inside the object like given below.
const movie1 = {
name : "Peanut Butter Falcon",
print : function (){
console.log(this.name)
}
}
const printThings = function (person){
console.log(`${person} is watching ${this.name}`)
}
const movie1 = {
name : "Peanut Butter Falcon"
}
const movie2 = {
name : "The imitation game"
}
The
printThings
function now has an parameter called person
.So how do we use the call method and pass the arguments?
printThings.call(movie1,"James") // output : "James is watching Peanut Butter Falcon"
printThings.call(movie2,"Peter") // output : "Peter is watching The imitation game"
The first argument is always the
this
argument , Rest can be passed after it like it is done in the above example.Let's take one more example :
const printprintThings = function (fname, lname){
console.log(`${fname} ${lname} is watching ${this.name}`)
}
const movie1 = {
name : "Peanut Butter Falcon"
}
const movie2 = {
name : "The imitation game"
}
printThings.call(movie1,"James","Bond") // output : "James Bond is watching Peanut Butter Falcon"
printThings.call(movie2,"Peter", "Pan") // output : "Peter Pan is watching The imitation game"
This example just has one more parameter than the previous one.
The only difference between
call
and apply
is that apply
method calls a function with a this
value and arguments as an array instead of passing the arguments individually like the call method.apply(thisArg,argArray)
We could use the previous example and use apply on it instead of call.
const printThings = function (fname, lname){
console.log(`${fname} ${lname} is watching ${this.name}`)
}
const movie1 = {
name : "Peanut Butter Falcon"
}
const movie2 = {
name : "The imitation game"
}
printThings.apply(movie1,["James","Bond"]) // output : "James Bond is watching Peanut Butter Falcon"
printThings.apply(movie2,["Peter", "Pan"]) // output : "Peter Pan is watching The imitation game"
It gives the same result.
Bind is different from call and apply in the sense that bind returns a new function instead of calling the existing function immediately.
bind(thisArg, arg1, ... , argN)
Now, we could bind the function to a
this
value .let printThings = function (fname, lname){
console.log(`${fname} ${lname} is watching ${this.name}`)
}
printThings = printThings.bind(movie1,"James","Bond")
printThings()
// output : "James Bond is watching Peanut Butter Falcon"
Thus we bind the printThings function to movie1 and we can call it whenever we want.
Let us take one more example.
"use strict"
this.movie = "Saving Private Ryan"
const outerFunction = function(){
const innerFunction = function (){
console.log(this.movie)
}
innerFunction()
}
outerFunction()
From what we have seen, the above code won't work, right? Since the context is lost.
Let us
bind
the outerFunction and use call
on the inner function and give them the this
value"use strict"
this.movie = "Saving Private Ryan"
let outerFunction = function(){
const innerFunction = function (){
console.log(this.movie)
}
innerFunction.call(this)
//Here "this" means the outerFunction
}
outerFunction = outerFunction.bind(this)
// Here "this" means the global context
outerFunction()
//Output : "Saving Private Ryan"
Finally, Let's try to fix the class which we made in the
Within a class
section. click here to take a look at it againclass theatre {
constructor(person,movie){
this.person = person
this.movie = movie
}
display(){
console.log(`${this.person} is watching ${this.movie}`)
}
}
const jack = new theatre("jack","inception")
const callback = jack.display
callback()
The only thing we have to do to get this working is to bind the method
display
to the this
value of the class.We can do this either in the constructor
class theatre {
constructor(person,movie){
this.person = person
this.movie = movie
this.display = this.display.bind(this) // Here
}
display(){
console.log(`${this.person} is watching ${this.movie}`)
}
}
const jack = new theatre("jack","inception")
const callback = jack.display
callback()
or bind it while passing it as a callback.
setTimeout(jack.display.bind(jack),1000)
//output : jack is watching inception
const callback = jack.display.bind(jack)
callback()
//output : jack is watching inception
Arrow functions are another way to solve the binding problem.
Arrow function have something called as a "lexical scope".
What that means is that arrow function does not have it's own
this
context, it borrows the context from the parent element or the context it was defined in.Hence, in the above example the outer function will get it's context from the global context and the inner function will get it's context from the outer function .
"use strict"
this.movie = "Saving Private Ryan"
const outerFunction = () => {
const innerFunction = () => {
console.log(this.movie)
}
innerFunction()
}
outerFunction()
//Output : "Saving Private Ryan"
We have already seen all the javascript specific reasons we bind a function or a method. The same applies for ReactJS.
In React we generally call a class method using an event handler like
onClick
, we pass the method we want to execute as a callback to the handler function.That is why the value of
this
is lost .By binding it explicitly we make sure it doesn't happen.

I hope you learnt something from this blog.
Let me know in the comments if you found this helpful .
See you in the next one :)
25