this en JavaScript
Tags: javascript, webdev, es6, spanish
Published: 2020-07-13 17:38:33

`this` es un término sencillo de comprender pero que puede ser motivo de varios dolores de cabeza al empezar a programar con JavaScript, es por ello que en este post tratare de explicarte sus ventajas y características al momento de usarlo en nuestros desarrollos.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wuu33bnz4znfpp9d2d6p.png)

## **Primero lo primero: El objeto Window**
Al abrir cualquier pestaña en cualquier navegador web se crea el objeto global `Window` que en palabras sencillas representa la venta que contiene todos los elementos del DOM y por ende donde están declaradas varias funciones que siempre usamos, como por ejemplo: `console.log()`, `length()`, etc.
Es importante resaltar que el objeto `Window` representa el **contexto global de JavaScript.**

## **¿Qué es this?**
**`this` es el objeto contexto de JavaScript en el cual se está ejecutando el código actual.**

Para comprender mejor todo veamos algo de código:

```javascript
const persona = {
  nombre:"Roberto",
  apellido: "Suarez",
  edad:29,
  getEdad: function (){
    return edad;
  }
}

console.log(persona.getEdad());
```

Tenemos un objeto persona donde almacenamos el nombre, el apellido, la edad y una función que devuelve la edad. Si intentamos mostrar la edad de la persona usando la función `getEdad()` esperaríamos que nos pinte por consola 29, ¿no es verdad? Pero la consola nos imprime el siguiente error: `Uncaught ReferenceError: edad is not defined`. ¿Porque la edad no está definida si la tenemos declarada dentro del objeto persona? 😵

Esto se debe a que la función `getEdad()` está buscando una variable edad en el contexto global, ósea, en el contexto de `Window`.

Si fuera de nuestro objeto persona declaramos una variable edad el código funciona:

```javascript
let edad = 50;
const persona = {
  nombre:"Roberto",
  apellido: "Suarez",
  edad:29,
  getEdad: function (){
    return edad;
  }
}

console.log(persona.getEdad());
//salida: 50
```

Podemos imprimir `this` en el contexto global para asegurarnos que retorna:

```javascript
let edad = 50;
console.log(this)
const persona = {
  nombre:"Roberto",
  apellido: "Suarez",
  edad:29,
  getEdad: function (){
    return edad;
  }
}

console.log(persona.getEdad());
```
Esto imprimirá el valor de la edad que es 50, y también el objeto `Window` completo con todas sus características, así nos damos cuenta en qué contexto nos encontramos.

El último fragmento de código no es erróneo pero no hace lo que deseamos, nosotros queremos que la función `getEdad()` acceda a la clave edad de nuestro objeto persona y por ende nos imprima 29 y no 50. Es aquí donde entra en acción la palabra reservada `this`.

```javascript
let edad = 50;
const persona = {
  nombre:"Roberto",
  apellido: "Suarez",
  edad:29,
  getEdad: function (){
    return this.edad;
  }
}

console.log(persona.getEdad());
//salida: 29
```
> *`this` es una palabra reservada del lenguaje, porque lo no se la declara como variable, simplemente existe para que los desarrolladores la puedan usar.*

Recordemos la definición de `this` en JavaScript:

**`this` es el objeto contexto de JavaScript en el cual se está ejecutando el código actual.**

`this` cambio el contexto del código, dentro de la función `getEdad()` `this` ya no apunta al objeto `Window`, ahora hace referencia al contexto donde se está ejecutando el código, osease, apunta al objeto `persona`, para verificar esto imprimamos por consola `this` pero dentro de `getEdad()`.

```javascript
const persona = {
  nombre:"Roberto",
  apellido: "Suarez",
  edad:29,
  getEdad: function (){
    console.log(this)
    return this.edad;  
  }
}

console.log(persona.getEdad());
//salida: Object {nombre: "Roberto", apellido: "Suarez", edad: 29, //getEdad()}
//29
```

> *Imprime `this` en diferentes contextos para saber exactamente donde apunta, con el tiempo y la práctica esto ya no será necesario pero para comenzar es muy recomendable.*

Podríamos acceder directamente al valor de edad dentro del objeto con la típica notación de punto, es perfectamente válido pero poco aconsejable considerando que nuestra aplicación puede escalar.

```javascript
const persona = {
  nombre:"Roberto",
  apellido: "Suarez",
  edad:29,
  getEdad: function (){
//código valido pero poco recomendable
    return persona.edad; 
  }
}

console.log(persona.getEdad());
//salida: 29
``` 

Ya para concluir analicemos un caso más:

```javascript

let persona ={
  "nombre": "Pedro",
  "apellido": "Salinas",
  "edad": 26,
  getEdad: function(){
    return this.edad;
  },
  "direccion":{
    "zona":"Los Pinos",
    getDireccion: function(){
      let nuevaDireccion = function(){
        console.log(this);// Window
        console.log("La direccion es en " + this.zona)
      }
      nuevaDireccion()
    }
  }
};

persona.direccion.getDireccion()
//salida: "La direccion es en undefined"
```

Si complicamos un poco más el ejemplo con anidamientos pueden pasar cosas algo extrañas, como por ejemplo que el contexto de `this` vuelva a ser `Window` (creado así un nuevo contexto) lo que no tiene sentido para nada! Muchos devs creen que esto se debe a un fallo de JavaScript pero puede ser solucionado con un hack bastante común y usado:

```javascript

let persona ={
  "nombre": "Pedro",
  "apellido": "Salinas",
  "edad": 26,
  getEdad: function(){
    return this.edad;
  },
  "direccion":{
    "zona":"Los Pinos",
    getDireccion: function(){
      let self = this;
      let nuevaDireccion = function(){
        console.log("La direccion es en " + self.zona)
      }
      nuevaDireccion()
    }
  }
};

persona.direccion.getDireccion()
//salida: Ls direccion es en Los Pinos
```

Creamos una variable auxiliar que contenga almacene el contexto actual, y usamos la variable para acceder a los campos requeridos.

> *La variable auxiliar por lo genera recibe el nombre de `self`, `that` o `me`.*

## **Referencias**

* https://www.youtube.com/watch?v=PDiw-9NpyRQ
* https://www.udemy.com/course/javascript-de-cero-hasta-los-detalles/

---

## **Conclusiones**
* Comprender `this` para desarrollar un código más legible y escalable es super importante.
* Recuerda: **`this` es el objeto contexto de JavaScript en el cual se está ejecutando el código actual.**
* En circunstancias muy concretas `this` puede tener comportamientos un tanto extraños, recomiendo imprimir hacer un `console.log(this);` cada vez que hayan dudas de contextos.