DEV Community

Cover image for `this` Just In: Discover the Hidden Powers of `this` in Javascript - The Beginners Guide To Javascript(Part 12)
Cameron Lucas
Cameron Lucas

Posted on

`this` Just In: Discover the Hidden Powers of `this` in Javascript - The Beginners Guide To Javascript(Part 12)

Hello, code lovers! Today, we're going to dive deep into the magical, sometimes maddening, yet absolutely essential world of the "this" keyword in JavaScript. If you've ever been left scratching your head by "this" (pun intended), you're in the right place. We're here to clear up the mystery, one code snippet at a time. Buckle up and let's get started!

What is "this"?

In JavaScript, "this" is a special keyword that refers to an object - the one that's currently being worked with. It's like JavaScript's version of a magic mirror, reflecting back the object in question. It can be anything from the global window object in a browser to a specific object you've created, depending on where and how you're using it.

const myObject = {
  property: 'I am a property!',
  method: function() {
    console.log(this.property);
  }
};

myObject.method();  // Outputs: 'I am a property!'
Enter fullscreen mode Exit fullscreen mode

In the example above, "this" refers to myObject. It's like the method is saying, "Within my current home (myObject), what is the property?"

Why does "this" exist?

So, why do we need "this" in JavaScript? It's all about context. JavaScript is an object-oriented language, which means we often interact with objects. "this" lets us access properties and methods within the object's context. It gives us a convenient way to refer to the object we're working on, without having to know its name.

Imagine you're a famous author signing autographs (nice, huh?). Instead of having to ask each fan's name, you could just refer to the current one as "this fan". In JavaScript world, that's what "this" is doing for us.

Automatic binding of "this" within functions

Now, how is the value of "this" set? Most often, it's bound automatically by JavaScript.

When you call a function as a method on an object, "this" gets automatically set to the object you're calling the method on. It's like JavaScript's way of saying, "Hey, you're working with this object now!"

const myObject = {
  greet: 'Hello',
  greetFunc: function() {
    console.log(this.greet);
  }
};

myObject.greetFunc(); // Outputs: 'Hello'
Enter fullscreen mode Exit fullscreen mode

In this example, "this" inside greetFunc automatically refers to myObject

The binding of "this" within arrow functions (ES2015)

Arrow functions, introduced in ES2015, have a unique feature: they do not bind their own "this". Instead, they inherit "this" from the parent scope. It's like a child inheriting their parent's eye color - it just happens!

const myObject = {
  greet: 'Hello',
  greetFunc: () => {
    console.log(this.greet);
  }
};

myObject.greetFunc(); // Outputs: undefined
Enter fullscreen mode Exit fullscreen mode

In this case, "this" does not refer to myObject, but the global object (like window in a browser), because that's the parent scope of the arrow function.

Explicitly determining the binding of "this"

But what if we want to control what "this" refers to? JavaScript has us covered with call, apply, and bind.

const myObject = {
  greet: 'Hello'
};

function greetFunc() {
  console.log(this.greet);
}

greetFunc.call(myObject);  // Outputs: 'Hello'
Enter fullscreen mode Exit fullscreen mode

In this example, we used call to make "this" inside greetFunc refer to myObject. apply works the same way, but with a slightly different syntax, and bind creates a new function with "this" bound to the specified object.

Bonus Material

Now, let's look at a common pitfall with "this" - nested functions:

const myObject = {
  greet: 'Hello',
  greetFunc: function() {
    function innerFunc() {
      console.log(this.greet);
    }
    innerFunc();
  }
};

myObject.greetFunc(); // Outputs: undefined
Enter fullscreen mode Exit fullscreen mode

In this case, "this" inside innerFunc does not refer to myObject, but the global object. This is because innerFunc is not a method on myObject, but a standalone function inside greetFunc.

To solve this, we can use an arrow function (which doesn't bind "this") or bind "this" to the function:

// Using an arrow function
const myObject1 = {
  greet: 'Hello',
  greetFunc: function() {
    const innerFunc = () => {
      console.log(this.greet);
    }
    innerFunc();
  }
};

myObject1.greetFunc(); // Outputs: 'Hello'

// Using Function.prototype.bind
const myObject2 = {
  greet: 'Hello',
  greetFunc: function() {
    const innerFunc = function() {
      console.log(this.greet);
    }
    innerFunc.bind(this)();
  }
};

myObject2.greetFunc(); // Outputs: 'Hello'
Enter fullscreen mode Exit fullscreen mode

And there you have it! You've just taken a whirlwind tour of "this" in JavaScript. Remember, "this" is like a mirror - it reflects the object you're working on, so you can access its properties and methods. It's a powerful tool, but with great power comes great responsibility. Use it wisely, and your JavaScript code will thank you!

Top comments (0)