DEV Community

Cover image for ๐Ÿ•ต๏ธโ€โ™‚๏ธ Unraveling the JavaScript "this" Enigma ๐Ÿ•ต๏ธโ€โ™€๏ธ
navvan
navvan

Posted on

๐Ÿ•ต๏ธโ€โ™‚๏ธ Unraveling the JavaScript "this" Enigma ๐Ÿ•ต๏ธโ€โ™€๏ธ

Visit our official platform: Navvan

Follow us on: LinkedIn | YouTube

1. Function Context ๐ŸŽญ

When a regular function is invoked, the value of this depends on how the function is called. Let's explore different scenarios: ๐Ÿ•ต๏ธโ€โ™‚๏ธ

1.1. Method Invocation ๐ŸŽจ

When a function is called as a method of an object, this refers to the object itself. ๐ŸŽฏ

const person = {
  name: 'Alice',
  greet() {
    console.log(`Hello, my name is ${this.name}! ๐Ÿ˜„`);
  },
};
person.greet(); // Output: Hello, my name is Alice! ๐Ÿ˜„
Enter fullscreen mode Exit fullscreen mode

In the example above, this inside the greet method refers to the person object. ๐Ÿ‘ค

1.2. Function Invocation ๐Ÿ“ž

When a function is invoked without an object reference, this refers to the global object (window in browsers, global in Node.js) in non-strict mode, or undefined in strict mode. ๐ŸŒ

function sayHello() {
  console.log(`Hello, ${this}! ๐Ÿ‘‹`);
}
sayHello(); // Output: Hello, [object Window]! ๐Ÿ‘‹ (in a browser)
Enter fullscreen mode Exit fullscreen mode

1.3. Constructor Invocation ๐Ÿ—๏ธ

When a function is invoked with the new keyword, a new object is created, and this refers to that newly created object. ๐Ÿ†•

function Person(name) {
  this.name = name;
}
const alice = new Person('Alice');
console.log(alice.name); // Output: Alice ๐Ÿ˜Ž
Enter fullscreen mode Exit fullscreen mode

1.4. Explicit Binding ๐Ÿ”—

You can explicitly set the value of this using the call(), apply(), or bind() methods. ๐ŸŽฏ

function greet() {
  console.log(`Hello, my name is ${this.name}! ๐Ÿ˜Š`);
}
const person = { name: 'Alice' };
greet.call(person); // Output: Hello, my name is Alice! ๐Ÿ˜Š
greet.apply(person); // Output: Hello, my name is Alice! ๐Ÿ˜Š
const boundGreet = greet.bind(person);
boundGreet(); // Output: Hello, my name is Alice! ๐Ÿ˜Š
Enter fullscreen mode Exit fullscreen mode

2. Arrow Functions ๐Ÿน

Arrow functions do not have their own this binding. Instead, they inherit this from the parent (surrounding) scope. ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ

const person = {
  name: 'Alice',
  greet() {
    const innerArrow = () => {
      console.log(`Hello, my name is ${this.name}! ๐Ÿ˜„`);
    };
    innerArrow();
  },
};
person.greet(); // Output: Hello, my name is Alice! ๐Ÿ˜„
Enter fullscreen mode Exit fullscreen mode

In the example above, the arrow function innerArrow inherits this from the surrounding greet method. ๐Ÿ‘ช

3. Class Context ๐ŸŽ“

In ES6 classes, this behaves differently in constructor functions, instance methods, and static methods. ๐Ÿซ

3.1. Constructor Functions ๐Ÿ”ง

In a class constructor, this refers to the newly created instance of the class. ๐Ÿ†•

class Person {
  constructor(name) {
    this.name = name;
  }
}
const alice = new Person('Alice');
console.log(alice.name); // Output: Alice ๐Ÿ˜Ž
Enter fullscreen mode Exit fullscreen mode

โš ๏ธ However, there's an interesting twist! If the constructor function returns another non-primitive value (like an object), the this binding is discarded, and the returned value becomes the result of the new expression. ๐Ÿ˜ฎ

function Car(model) {
  this.model = model;
  return { year: 2023 };
}

let myCar = new Car("Tesla");
console.log(myCar.model); // Output: undefined
console.log(myCar.year); // Output: 2023
Enter fullscreen mode Exit fullscreen mode

3.2. Instance Methods ๐ŸŽญ

In an instance method, this refers to the instance of the class on which the method is called.

3.3. Static Methods ๐Ÿ“Š

In a static method, this refers to the class itself, not an instance of the class. ๐Ÿ“ˆ

class Animal {
  makeSound() {
    console.log(this); // `this` refers to the instance
  }

  static getSpecies() {
    console.log(this); // `this` refers to the class
  }
}

const dog = new Animal();
dog.makeSound(); // Output: instance of Animal
Animal.getSpecies(); // Output: Animal
Enter fullscreen mode Exit fullscreen mode

๐ŸŒŸ In derived classes, constructors have slightly different behavior. Unlike base class constructors, derived constructors have no initial this binding. Calling super() creates the this binding within the constructor.

๐Ÿšจ It's important to remember that referring to this before calling super() will throw an error. ๐Ÿšจ

class Vehicle {}
class Car extends Vehicle {
  constructor() {
    super(); // Creates `this` binding
    console.log(this); // Now, `this` is available
  }
}

new Car();
Enter fullscreen mode Exit fullscreen mode

4. Global Context ๐ŸŒ

In the global execution context, this refers to the global object (window in browsers, global in Node.js). ๐ŸŒ

console.log(this === window); // Output: true ๐Ÿ˜„ (in a browser)
Enter fullscreen mode Exit fullscreen mode

5. Event Handlers ๐ŸŽ‰

When a function is used as an event handler, this refers to the element that triggered the event. ๐ŸŽฏ

<button id="myButton">Click me! ๐Ÿ–ฑ๏ธ</button>
Enter fullscreen mode Exit fullscreen mode
const button = document.getElementById('myButton');
button.addEventListener('click', function () {
  console.log(this === button); // Output: true ๐Ÿ˜„
});
Enter fullscreen mode Exit fullscreen mode

In the example above, this inside the event handler function refers to the button element. ๐Ÿ”˜

6. Strict Mode ๐Ÿšจ

In strict mode, the value of this remains whatever it was set to when entering the execution context. If this is not defined, it remains undefined. ๐Ÿค”

function strictFunc() {
  return this;
}
console.log(strictFunc() === undefined); // Output: true ๐Ÿ˜…
Enter fullscreen mode Exit fullscreen mode

Conclusion ๐ŸŽ‰

Phew! We've covered some ground in this little dive into the context of this in JavaScript. From normal to arrow functions, classes to event handlers, and strict mode considerations, this plays a crucial role in understanding how JS code behaves. ๐ŸŒŸ

Remember, the value of this is determined by how a function is called, not where it's defined. ๐Ÿ’ช

If you enjoyed this article, please make sure to Subscribe, Like, Comment, and Connect with us today! ๐ŸŒ

Visit our official platform: Navvan

Follow us on: LinkedIn | YouTube

Top comments (0)