objeto-this-en-javascript

How this Works in JavaScript

  • 4 min

In simple terms, this is a special keyword in JavaScript that refers to the current object or execution context in which a function is being called.

In JavaScript, the behavior of this is one of the most difficult concepts to understand because it is somewhat different from most languages.

The important thing is that this always refers to the execution context of the function. This execution context can be:

  • The global context when calling a function from outside an object.
  • The object that calls a method from within the object.
  • A specific object that we explicitly “force” (using methods call(), apply(), or bind()).

Let’s look at each one in detail 👇

Behavior of ‘this’

In JavaScript, the value of this depends on how the function is called, not on how it is defined.

In regular functions

When a function is invoked in a simple manner (without using objects or special methods), this refers to the global context.

function greet() {
  console.log(this);  // `this` refers to the global object
  console.log("Hello!");
}

greet();
Copied!

In this case, when saludar() is executed, the value of this is the global object. (window in a browser or global in Node.js)

In strict mode ("use strict";), this does not refer to the global object, but will be undefined.

From object methods

When a function is invoked as a method of an object, the value of this refers to the object to which the method belongs.

const person = {
  name: "Luis",
  greet: function() {
    console.log(this.name);  // `this` refers to the `person` object
  }
};

person.greet();  // Output: "Luis"
Copied!

In this case, when persona.saludar() is invoked, this refers to the persona object, which allows access to the nombre property within the method.

Losing the ‘this’ object

One of the biggest headaches with this is that it’s easy to “lose” the reference to the object we intended.

When we define a function inside a method, if we’re not careful, this might refer to the global object instead of the expected object.

const person = {
  name: "Luis",
  greet: function() {
    function innerGreet() {
      console.log(this.name);  // `this` refers to the global object
    }
    innerGreet();
  }
};

person.greet();  // Error: `this.name` is `undefined`, since `this` is the global object
Copied!

In this example,

  • Inside saludar(), we define the function saludarInterno().
  • However, this in saludarInterno() does not refer to persona, but to the global context.
  • This can cause the nombre property to not be accessible correctly.

‘this’ in arrow functions

Arrow functions in JavaScript have special behavior regarding this.

Instead of setting their own this value, arrow functions inherit the value of this from the lexical context in which they were defined.

const person = {
  name: "Luis",
  greet: function() {
    const sayHello = () => {
      console.log("Hello, I am " + this.name); // `this` refers to `person`
    };
    sayHello();
  }
};

person.greet(); // "Hello, I am Luis"
Copied!

In this case,

  • persona is an object with a property nombre and a method saludar.
  • Inside the saludar method, we define an arrow function called decirHola.
  • The arrow function inherits the this context from the saludar method, which points to the persona object.
  • When calling decirHola, it uses the “correct” value of this and accesses persona.nombre.

Explicitly modifying

In JavaScript, we can explicitly modify the value of this using the methods call(), apply(), and bind().

These methods allow us to set the execution context for a function, regardless of how it is invoked.

Summary of everything we’ve seen:

  • In regular functions, this refers to the global context.
  • In object methods, this refers to the object containing the method.
  • In functions inside methods, care must be taken, as this can change depending on the context of the inner function.
  • Arrow functions do not have their own this, but inherit the this from their lexical context.
  • call(), apply() and bind() allow explicitly changing the value of this when invoking a function.