JavaScript 'this' - Four rules to know
Tags: javascript, webdev, tutorial, programming
Published: 2021-07-26 16:51:01

When you use `this` in your code, it automatically resolves to an object or scope depending on the context at which is was defined.

But what are those possible contexts a `this` call can refer to? Additionally, how can we use that information to find out which object a `this` call will resolve to? Let's find out!

### this Context
When used in a function, the `this` keyword simply points to an object which it is bound to. In simple terms, it answers the question of where it should get some value or data from:

```js
function alert() { 
  console.log(this.name + ' is calling'); 
}
```

In the function above, the `this` keyword is simply referring to an object to which it is bound to access the "name" property from it.

But how do you know what object or scope the function is bound to? How do you make out what `this` is referring to?

To unravel that, we need to understand the various binding rules that guide the `this` behavior.

### Types of Binding in JavaScript
Generally, there are four kinds of bindings:

- Default Binding
- Implicit Binding
- Explicit Binding
- Constructor Call Binding

### Default Binding in JavaScript
One of the first rules to remember is that if the function housing a `this` reference is a standalone function, then that function is bound to the global object.

```js
function alert() { 
  console.log(this.name + ' is calling'); 
}


const name = 'Kingsley'; 
alert(); // Kingsley is calling
```

`name()` is a standalone, unattached function. As per the rule, it is bound to the global scope. Hence, the this.name reference resolves to the global variable const name = 'Kingsley'.

This rule, however, doesn't hold if `name()` were to be defined in strict mode as so:

```js
function alert() { 
  'use strict'; 
  console.log(this.name + ' is calling'); 
}

const name = 'Kingsley'; 
alert(); // TypeError: `this` is `undefined`
```


### Implicit Binding in JavaScript
Another scenario to look out for is whether the function is attached to an object (its context) at the call site.

According to the binding rule in JavaScript, a function can use an object as its context only if that object is bound to it at the call site. This form of binding is known as implicit binding.

Here is what I mean by that:


```js
function alert() { 
  console.log(this.age + ' years old'); 
}

const myObj = {
  age: 22,
  alert: alert
}

myObj.alert() // 22 years old
```

Put simply, when you call a function using dot notation, this is implicitly bound to the object the function is being called from.

In this example, since alert is being called from myObj, the this keyword is bound to myObj. So when alert is called with myObj.alert(), this.age is 22, which is the age property of myObj.

Let's look at another example:

```js
function alert() { 
  console.log(this.age + ' years old'); 
}

const myObj = {
  age: 22,
  alert: alert,
  nestedObj: {
    age: 26,
    alert: alert
  }
}

myObj.nestedObj.alert(); // 26 years old
```

Here, because `alert` is ultimately being called from nestedObj, `this` is implicitly bound to `nestedObj` instead of `myObj`.

An easy way to figure out which object this is implicitly bound to is to look at which object is to the left of the dot (.):

```js
function alert() { 
  console.log(this.age + ' years old'); 
}

const myObj = {
  age: 22,
  alert: alert,
  nestedObj: {
    age: 26,
    alert: alert
  }
}

myObj.alert(); // `this` is bound to `myObj` -- 22 years old
myObj.nestedObj.alert(); // `this` is bound to `nestedObj` -- 26 years old
```

### Explicit binding in JavaScript
We saw that implicit binding had to do with having a reference in that object.

But what if we want to force a function to use an object as its context without putting a property function reference on the object?

We have two utility methods to achieve this: `call()` and `apply()`.

Along with a couple other set of utility functions, these two utilities are available to all functions in JavaScript via the `[[Prototype]]` mechanism.

To explicitly bind a function call to a context, you simply have to invoke the `call()` on that function and pass in the context object as parameter:

```js
function alert() { 
  console.log(this.age + ' years old'); 
}

const myObj = {
  age: 22
}

alert.call(myObj); // 22 years old
```

Now here's the fun part. Even if you were to pass around that function multiple times to new variables (currying), every invocation will use the same context because it has been locked (explicitly bound) to that object. This is called hard binding.

```js
function alert() { 
  console.log(this.age); 
} 

const myObj = { 
  age: 22 
}; 

const bar = function() { 
  alert.call(myObj); 
}; 

bar(); // 22
setTimeout(bar, 100); // 22 
// a hard-bound `bar` can no longer have its `this` context overridden 
bar.call(window); // still 22
```

Hard binding is a perfect way to lock a context into a function call and truly make that function into a method.

### Constructor Call Binding in JavaScript

The final and perhaps most interesting kind of binding is the `new` binding which also accentuates the unusual behaviour of JavaScript in comparison to other class-based languages.

When a function is invoked with the `new` keyword in front of it, otherwise known as a constructor call, the following things occur:

- A brand new object is created (or constructed)
- The newly constructed object is [[Prototype]]-linked to the function that constructed it
- The newly constructed object is set as the this binding for that function call.

Let's see this in code to get a better understanding:

```js
function giveAge(age) { 
  this.age = age; 
} 

const bar = new giveAge(22); 
console.log(bar.age); // 22
```

By calling giveAge(...) with new in front of it, we’ve constructed a new object and set that new object as the this for the call of foo(...). So new is the final way that you can bind a function call’s this .


### SUMMARY
To summarize, the this keyword, when used in a function, binds that function to a context object.

There are four kinds of bindings: default binding, implicit binding, explicit binding and constructor call binding (new).

Knowing these four rules will help you easily discern the context for a `this` reference.

I hope you got something valuable from this article. If you are learning JavaScript, here are some other articles that might interest you:

 - [Web Development roadmap for beginners](https://ubahthebuilder.tech/complete-web-development-roadmap-for-newbies) 

 - [50 Web Development terms to know](https://ubahthebuilder.tech/50-web-development-terms-all-programmers-should-know) 

 - [Introduction to Asynchronous Programming in JavaScript](https://ubahthebuilder.tech/introduction-to-asynchronous-programming-with-javascript) 

Thank you for reading and see you soon.


> 
P/S: If you are learning JavaScript, I created an eBook which teaches 50 topics in JavaScript with hand-drawn digital notes. Check it out [here](gum.co/js-50)