Why is the ‘this’ Keyword Important in JavaScript?
Tags: javascript, webdev, beginners, programming
Published: 2023-11-14 11:10:42


Ever heard that mastering JavaScript is like joining an exclusive club, and the secret password is understanding `“this”`? It’s the cool kid on the coding block! If you’re diving into JavaScript, consider getting to know how the `“this”` keyword grooves through your code — it’s your ticket to an awesome coding journey!

The behavior of `“this”` can often seem mysterious or inconsistent until it “clicks.” But once you truly understand this, you’ll code with JavaScript much more confidently.

Let me try to break it down in plain English terms.

---

## What is “this”?

The `“this”` keyword is a way to refer to the object that “owns” the code from which it is called. *But what exactly does that mean? *Well, JavaScript functions operate differently than those in other languages like Python or Java.

> In JavaScript, the context or value of `‘this’` is determined by how the function is called rather than where it is declared.

To understand this better, let’s look at a simple example. Say I have an object called `myObject` with a method called `myMethod`:

```javascript
const myObject = {
  name: "John",
  myMethod: function() {
     console.log(this.name); 
  }
}
```

If I call myMethod like this:

```javascript
myObject.myMethod();
```
Inside the function, `“this”` would refer to `myObject`, so it would correctly log `“John”` to the console.

However, if I removed the method from the object and called it on its own:

```javascript
const myMethod = myObject.myMethod;
myMethod();
```

Now `“this”` would refer to the global object (window in browsers) instead of `myObject`. Since the global object doesn’t have a `‘name’` property, it would log undefined.

---

## How “this” is determined?

So how exactly is this determined? It comes down to the call-site context, or how the function is called. 

In JavaScript, `“this”` bindings are determined by four key rules:

**=> 1. Default binding**

In a regular function call, `“this”` will default to the global object (window in browsers).

```javascript
function sayName() {
  console.log("Name: ", this.name);
}
sayName(); // this = window
    
// output: "Name: " because window doesn't have a name property
```

**=> 2. Implicit binding**

When a function is called as a method, `“this”` is set to the object before the dot.

```javascript
let person = {
  name: "John",
  sayName() {
    console.log("Name: ", this.name);
  }
}
person.sayName(); // this = person
    
// Output: "Name: John"
```

**=> 3. Explicit binding**

Methods like `call()`, `apply()`, and `bind()` allow manually setting the this value.

```javascript
function sayName() {
  console.log("Name: ",this.name);
}
sayName.call({name: 'John'}); // this = {name: 'John'} 
    
// output: "Name: John"
```

**=> 4. New binding**

If new is used when calling a function, `“this”` is bound to the newly created object.

```javascript
function Person(name) {
  this.name = name;
}
    
new Person('John'); // this = new Person object
```

Understanding these rules is key to properly using this in JavaScript. The binding is determined at call-time rather than define-time.

---
## What does “this” refer to in regular vs arrow functions?

In regular functions, the value of `“this”` depends on how the function is called. 

If a regular function is called as a method of an object, `“this”` will usually refer to that object.

```javascript
const myObject = {
  name: 'John',
  sayName: function() {
     console.log(this.name);
  }
}
    
myObject.sayName(); // Outputs 'John'; this = myObject
```

Here, `“this”` refers to myObject because `sayName` was called as a method of `myObject`.

In arrow functions, the value of `“this”` is lexically scoped, meaning it retains the value of `“this”` from its enclosing scope.

In other words, the `“this”` value inside an arrow function is the same as the `“this”` value outside the arrow function.

```javascript
const myObject = {
  name: 'John',
  sayName: () => {
    console.log(this.name); 
  }
}
    
myObject.sayName(); // Outputs undefined; this = window
```

Now `“this”` refers to the global context (window) rather than myObject, since arrow functions don’t have their own `“this”` binding.

---

## Common pitfalls with ‘this’

Now that we know how `“this”` works, let's look at some common mistakes developers make when dealing with it:

**=> Forgetting the binding context** — It’s easy to forget that `“this”` changes based on how a function is called. Make sure to mentally trace the call stack.

**=> Ignoring arrow functions** — Arrow functions do not have their own `“this”`; they inherit it from the enclosing context.

**=> Losing binding in callbacks** — When passing a method as a callback, its `“this”` binding can be lost unless bound.

**=> Not understanding default binding** — Easy to forget regular function calls default `“this”` to the global/window object.

**=> Not applying explicit binding** — `.call()`, `.apply()` and `.bind()` are useful to ensure `“this”` acts as intended when needed.

Knowing these common pitfalls and properly understanding the rules of `“this”` in depth will help avoid many issues down the road. With practice, you'll get more comfortable tracing `“this”` bindings in your code.

---

## Conclusion

The `“this”` keyword is complex because it behaves dynamically based on calling context. But making sense of the core rules around default binding, implicit binding, explicit binding, and new binding provides clarity.

Pay attention to how functions are called rather than just how they're defined to fully understand `“this”`.

With experience, you'll develop an intuition for how `“this”` bindings work in JavaScript. Its proper use is essential for clean, clear code - especially as projects grow larger.

I hope this post helps demystify an important JavaScript concept!

## 🔥 Wait! 🔥

Give that like button some love! And if you’re feeling extra cheeky, hit follow too!
>  *Follow me on Instagram: [Click Here](https://www.instagram.com/codingwithjd/)*