Intro
Simply put, this is a special variable that is created for every Execution Context.
Once this has been created for the Execution Context (EC), it becomes a “keyword”. Then, it points to (or takes the value of) the parent of whatever function has used this. The interesting thing about this is that it behaves differently with respect to how it is used and called in different use cases. Let us see them one by one.
Different scenarios of ’this’ -
#1: Default Binding
A simple program that has nothing but this statement - console.log(this) - will show that this will point to the global window object, like so -
#2: Implicit Binding
’this’ in a method
A method is any function that is defined inside an object.
In the example below, this will point to the parent object of the method that calls this. Since getCurrentYear is the method that calls this, the value of this will now point to the parent object - details. Hence, this.futureYear is equal to typing details.futureYear.
const details = {
name: 'Vinoo',
futureYear: 2049,
getCurrentYear: function () {
console.log(2199 - this.futureYear)
console.log(this)
}
}
details.getCurrentYear() // 150
As we can see, we get the result 150 when the function is called. The value for futureYear was accessed through the this variable. The value of this itself is the details object -
’this’ in a function call
In a regular function call with strict mode enabled, this will return undefined 👇
Otherwise, this will point to the global window object 👇
’this’ in Arrow Functions
In arrow functions, this simply points to the this of its surrounding function - which means this points to the lexical scope/parent scope. This goes to say that arrow functions do not get their own this.
Example -
#3: Explicit Binding
As the name suggests, explicit binding is a way to explicitly bind the value of this to a specific object. There are 3 ways to do this -
-
call()- Let’s say that our function is outside the object, and we still wantthisin the function to point to the object. We can do that as follows -
Here, we are “binding” the object
detailsto the functiondisplayName()so that thethisvariable in that function can point to the desired object. If we DO NOT use the “call” binding, then as usual,thiswill simply point to the global window object.Now, what if we have multiple arguments to be passed? Look at the example below -
call()successfully binds the details we have passed to thepersonobject and then the elements of thehobbiesarray, individually. But this is not the most efficient to bind things, is it? This is where theapply()method helps us. -
apply()- this method works exactly likecall()except that we can pass the array variable itself as a parameter instead of the array elements individually. Everything else stays the same -
-
bind()- this method too, is almost no different from thecall()orapply()methods but there is an important advantage to using it. First, let’s look at an example -
Notice how we assigned the
bind()method to a variablefooand then called it as a function? This is becausebind()returns a new function that we can then invoke anywhere we wish. Now for the advantage bit -foodoes not even get instantiated anywhere, does not have a reference, nothing. Even though thepersonobject does not have a property namedfoo, we can still explicitly bindfootopersonmuch later in the program such thatpersonwill now recognisefooas its own method.
#4: ’new’ Binding
new is yet another special keyword that is exclusively used in the case of constructor functions. These are used to create new objects. Let’s look at this example -
let Wizard = function(name, spell) {
this.name = name
this.spell = spell
this.castMagic = function() {
console.log(this.name + ' has cast this spell - ' + this.spell)
}
}
let hermione = new Wizard('Hermione', 'Occulus Reparo')
let ron = new Wizard('Ron', 'Sunshine Daisies')
new is used to denote that we are creating a new object (instantiating) for the Wizard function. Note that Wizard is capitalised when we use new - a simple convention to differentiate, and also specify that this variable will always point to the empty object created by new. This is how we can get new instances easily for the same function with different arguments. Just simple Object Oriented Programming in action 😎
We will study more about constructors and classes in depth in a later post.
#5: HTML Event Element Binding - ’this’ in Event Listeners
In case of event listeners, this points to the DOM element that the handler is attached to. Example -
sendBtn.addEventListener('click', function () {
console.log(2 + 3)
console.log('Value of this - ', this)
})
Here, on clicking the button ‘Send’, the value of this will indeed be the DOM element button that the function/handler is attached to.
NOTE - if this function/handler is an arrow function, then the value of this again defaults to the global window object, like so -
sendBtn.addEventListener('click', () => {
console.log(2 + 3)
console.log('Value of this - ', this)
})
Closing Notes
That was it for this!
We will study more about how this is important for classes, constructors, and object oriented programming in the later posts.
Until the next one!
Keep shipping 🚀