How 'this' works in JavaScript

This in JavaScript refers to the object that is executing the current function. In other words, this is a reference to the object that owns the function being executed. Understanding this is crucial for writing effective JavaScript code, especially when working with object-oriented programming.

Before diving into practical examples, let's first look at the different ways this can be assigned a value in JavaScript.

  1. Implicit binding: In this case, this refers to the object that is to the when the function is called. For example:
let person = {
  name: 'John Doe',
  greeting: function () {
    console.log(`Hello, my name is ${this.name}`);
  }
}
person.greeting(); //Output: Hello, my name is John Doe
  1. Explicit binding: In this case, "this" is explicitly set using the call, apply, or bind methods. For example:
let person = { name: 'John Doe' };
let greet = function () {
  console.log(`Hello, my name is ${this.name}`);
}.bind(person);
greet(); //Output: Hello, my name is John Doe
  1. New binding: In this case, "this" refers to the object that is created when a constructor function is called using the new keyword. For example:
function Person(name) {
  this.name = name;
  this.greeting = function () {
    console.log(`Hello, my name is ${this.name}`);
  };
}
let john = new Person('John Doe');
john.greeting(); //Output: Hello, my name is John Doe
  1. Window binding: If "this" is not assigned a value by any of the above methods, it defaults to the global window object(in a browser). For example:
let name = 'Global Name';
let greet = function () {
  console.log(`Hello, my name is ${this.name}`);
};
greet(); //Output: Hello, my name is Global Name

In ES6, the way "this" works has changed, with the introduction of arrow functions. Arrow functions do not have their own this, instead, they inherit the this value from the surrounding scope. For example:

let person = {
  name: 'John Doe',
  greeting: () => {
    console.log(`Hello, my name is ${this.name}`);
  }
}
person.greeting(); //Output: Hello, my name is

As you can see, the greeting function, which is an arrow function, does not have its own this value from the surrounding scope, which is the global window object.

Here's a more practical example of how arrow functions in ES6 inherit the this value from the surrounding scope:

let person = {
  name: 'John Doe',
  hobbies: ['reading', 'swimming', 'hiking'],
  showHobbies: function () {
    this.hobbies.forEach(hobby => {
      console.log(`${this.name} likes ${hobby}`);
    });
  }
}
person.showHobbies();
//Output:
//John Doe likes reading
//John Doe likes swimming
//John Doe likes hiking

In this example, the showHobbies function uses an arrow function as a callback to the forEach method. The arrow function inherit the this value from the surrounding showHobbies function, which is the person object. This allows us to use this.name inside the arrow function to access the name property of the person object.

Conclusion:

In conclusion, "this" in JavaScript refers to the object that is executing the current function, add its value can be assigned implicitly, explicitly via the new keyword or default to the global window object. In ES6, arrow functions have changed the way "this" works by inheriting the this value from the surrounding scope.

We hope this post has been helpful in explaining the concept of "this" in JavaScript.