La Esquina del Código
Un blog de Carlos Reyes Web
Volver al inicio¿Qué es el this en JavaScript?

¿Qué es el this en JavaScript?

¿Conoces algo más polivalente que el this en JavaScript? Personalmente, no creo que exista algo que se le parezca. Y es que el this ha sido objeto de un sinfín de confusiones entre los más novatos y experimentados de este lenguaje, pues su valor depende de cómo, cuándo y dónde lo evalúes; es como el elemento cuántico del lenguaje. Por eso, en este artículo, exploraremos de forma muy práctica qué es el this en JavaScript, cómo funciona y cuál es su valor en diferentes contextos.

¿Qué es el this?

Es una palabra reservada en JavaScript que podemos utilizar para referirnos al contexto en el que se invoca, por lo que su valor implícito puede variar durante la ejecución del código.

this en el contexto global

Decimos que el contexto global es todo lo que se encuentra fuera de cualquier bloque de código.

En este caso, this siempre hace referencia al objeto global:

console.log(this === window) // true

this.awesomeNumber = 37
console.log(window.awesomeNumber) // 37

this en el contexto de una función

Si invocamos this dentro de una función, su valor cambia dependiendo de cómo ejecutamos la función.

Llamada simple

Si es una llamada simple y no está en modo estricto, this devuelve el objeto global.

function whoIsThis() {
  return this
}

console.log(whoIsThis() === window) // true, porque window es un objeto global

Llamada simple (modo estricto)

Si es una llamada simple y está en modo estricto, this conserva el valor que haya recibido antes de la ejecución de la función, y devuelve undefined si no ha recibido ninguno.

function whoIsThis() {
  'use strict'
  return this
}

console.log(whoIsThis()) // undefined

Como método de objeto

Si la función es el método de un objeto y se invoca como tal, this es el objeto en sí mismo.

const me = {
  name: 'Carlos Reyes',
  sayMyName() {
    return this.name
  },
}

console.log(me.sayMyName()) // 'Carlos Reyes'

Función asignada como método de un objeto

Cuando se define una función y luego se asigna como método de un objeto, this dentro de la función se refiere al objeto al que se ha asignado la función.

function sayHello() {
  console.log(`Hola, soy ${this.name}.`)
}

const person = {
  name: 'Juan',
  greet: sayHello, // asignamos 'sayHello' a la propiedad 'greet'
}

person.greet() // Hola, soy Juan.

Función asignada como método de un objeto anidado

Cuando se define una función y se asigna como propiedad de un objeto más anidado, this dentro de la función se refiere al objeto más inmediato que contiene la función como propiedad.

const myObj = {
  myMethod: function () {
    console.log(this)
  },
  nestedObj: {
    nestedMethod: myObj.myMethod,
  },
}

myObj.myMethod() // Imprime el objeto myObj
myObj.nestedObj.nestedMethod() // Imprime el objeto nestedObj

Como un Getter o un Setter

Si el método en cuestión es un getter o un setter, this es el objeto al que pertenece.

const me = {
  firstName: 'Carlos',
  lastName: 'Reyes',
  get fullName() {
    return `${this.firstName} ${this.lastName}`
  },
  set fullName(fullName) {
    const [firstName, lastName] = fullName.split(' ')
    this.firstName = firstName
    this.lastName = lastName
  },
}

console.log(me.fullName) // 'Carlos Reyes'
me.fullName = 'Pedro Perez'
console.log(me.fullName) // 'Pedro Perez'

Como un constructor

Si se llama la función como un constructor (esto es, hacer uso de la palabra new), this es el nuevo objeto que está siendo construido, a menos que la función retorne un objeto, en cuyo caso this será ese objeto retornado.

function Person(name, age) {
  this.name = name
  this.age = age
}

const me = new Person('Carlos', 22)
console.log(me.name) // 'Carlos'
console.log(me.age) // 22
// Si el constructor retorna un objeto, entonces
function Person(name, age) {
  this.name = name // esta línea se considera muerta
  this.age = age // esta también
  return { name: 'Juan', age: 30 }
}

const person = new Person('Carlos', 22)
console.log(person.name) // 'Juan'
console.log(person.age) // 30

Usando .call() y .apply()

Si se llaman los métodos especiales .call() y .apply() de cualquier función con un objeto particular como primer argumento, entonces this será enlazado explícitamente a ese objeto durante su ejecución.

const person = {
  name: 'Ana',
  age: 25,
  sayHello: function () {
    console.log(`Hola, mi nombre es ${this.name} y tengo ${this.age} años.`)
  },
}

const person2 = {
  name: 'Juan',
  age: 30,
}

person.sayHello() // Hola, mi nombre es Ana y tengo 25 años.
person.sayHello.call(person2) // Hola, mi nombre es Juan y tengo 30 años.
person.sayHello.apply(person2) // Hola, mi nombre es Juan y tengo 30 años.

Usando .bind()

Si se llama al método especial .bind() de cualquier función con un objeto como primer argumento, ese objeto será el nuevo y permanente this de la función que retorna este método especial. Es decir, .bind() crea una nueva función con el mismo alcance y cuerpo de su dueño, pero con un this diferente al original.

const person = {
  name: 'Juan',
  age: 30,
  sayHi() {
    console.log(`Hola, mi nombre es ${this.name} y tengo ${this.age} años.`)
  },
}

const newPerson = {
  name: 'María',
  age: 25,
}

const newSayHi = person.sayHi.bind(newPerson)

newSayHi() // Hola, mi nombre es María y tengo 25 años.

Como un listener en el DOM

Por último, cunado la función es utilizada como un listener de un evento en el DOM, su this es el elemento del DOM al que apunta este evento.

const button = document.querySelector('#myButton')

function changeContent(e) {
  console.log(this === button) // true
  this.textContent = '¡Clic realizado!'
}

button.addEventListener('click', changeContent)

Ahora que ya conoces el multiverso de this, es hora de ponerlo en práctica construyendo tus propios ejemplos para cada escenario. ¡Más nunca lo olvidarás!

Comparte este artículo con tus colegas programadores para alegrarles el día.

Compartir en Twitter