Funciones de flecha en JavaScript + this
Tags: javascript, webdev, programming, spanish
Published: 2022-06-13 21:54:22

Las funciones de flecha en JavaScript nos brindan la posibilidad de escribir funciones sin utilizar la palabra clave `function`, pero mas allá de la sintaxis, las funciones de flecha o arrow functions tienen algunas particularidades y diferencias de cuando creamos funciones de manera "tradicional".

###Sintaxis
```
//Declaración de función
function sayHello() {
  console.log("Hi")
}

//Expresión de función
const sayHello = function() {
  console.log("Hi")
}

//Función de flecha
const sayHello = () => console.log("Hi")
```

Como mencioné al inicio de este artículo, las funciones de flecha nos permiten crear funciones de una manera mas compacta en algunos casos, ahora hablemos de sus diferencias y algunas limitaciones.

***

###This y Funciones de flecha

Una de las diferencias mas llamativas es cuando asociamos el concepto de `this` en JavaScript con las funciones de flecha.

####Como this determina su valor?.

La palabra clave `this` y su valor dependen del **contexto de ejecución** o como se invoca determinada función o método en JavaScript.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/saw45gak7ej3jqs9e3d6.gif)

Aprendiendo este concepto (this keyword) yo también estaba confundido como la imagen mas arriba :satisfied:, pero no te preocupes espero que con este artículo despejes tus dudas.

***

**En los navegadores el valor de `this` ejecutándose en un contexto global es el objeto window.**

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

###En una función

Cuando utilizamos `this` dentro de una función, su valor depende del contexto de ejecución de la función.

```
function sayHello() {
  console.log(this)
}
sayHello() *contexto de ejecución global

// Window {...}
```

***

###En un objeto declarado

Al utilizar `this` dentro de un método en un objeto declarado, el valor de `this` será el del objeto en el que se está llamando el método.

```
const nameObj = {
  name: "Alfredo",
  getUserName: function () {
    console.log(this)
  }
}

nameObj.getUserName()

// {name: 'Alfredo', ...}
``` 

En este ejemplo a continuación, el valor de this se determina de acuerdo a su referencia mas cercana.

``` 
const nameObj = {
  name: "Alfredo",
  nested : {
    lastName: "Moscoso",
    getUserName: function () {
      console.log(this);
    },
  }
};

nameObj.nested.getUserName()

//{lastName: 'Moscoso', ...}

``` 
Como podemos ver su valor depende del contexto de ejecución del método.

***

###En una función constructora 

Si trabajamos con una función constructora y la palabra clave `new` su valor está vinculado al nuevo objeto que se está creando.

``` 
function Car(model, year) {
  this.model = model;
  this.year = year;
}

const ford = new Car("Ford", "1970")
console.log(ford.year) // 1970

const chevrolet = new Car("Chevrolet", "1956")
console.log(chevrolet.year) // 1956
``` 

###En los métodos call, apply y bind 

Con los métodos de funciones `call` y `apply` podemos enlazar el valor de `this` dentro de una función a un objeto.

**call()**

``` 
const nameObj ={
  name: "Alfredo"
}

function getUserName(lastName) {
  console.log(`${this.name} ${lastName}`)
}

getUserName.call(nameObj, "Moscoso")

//Alfredo Moscoso

``` 
**apply()**

``` 
const nameObj ={
  name: "Alfredo"
}

function getUserName(lastName) {
  console.log(`${this.name} ${lastName}`)
}

getUserName.apply(nameObj, ["Moscoso"])

//Alfredo Moscoso
``` 

**bind()**

En el método `bind` también podemos enlazar un valor de `this` con un objeto, la diferencia es que el método `bind` crea una nueva función que podemos llamar luego. 

``` 
const nameObj ={
  name: "Alfredo"
}

function getUserName(lastName) {
  console.log(`${this.name} ${lastName}`)
}

const user = getUserName.bind(nameObj, "Moscoso")
user()

//Alfredo Moscoso
``` 

Más información sobre estos métodos.
https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Function/call

Ahora que ya vimos algunos ejemplos y como `this` modifica su valor, veamos como se comportan las funciones de flecha y la palabra clave `this`.

***

###This en una función de flecha

``` 
const nameObj = {
  name: "Alfredo",
  getUserName: () => console.log(this)
}

nameObj.getUserName() // ???
``` 

Cual crees será la salida del código ?

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7bnwn4nrceoruketjj3.gif)

***

La salida de este código es la siguiente, el window object. 

`// Window {...}`

Esto ocurre porque las funciones de flecha no tienen un `this` atado a ellas o no predeterminan `this` al alcance de Window, estas se ejecutan en el alcance en que fueron creadas.

En este ejemplo el método getUserName() está retornando una función de flecha, como estas funciones no tienen su propio `this`, el valor de `this` es el del ámbito adjunto, el del método getUserName() y como estamos utilizando una función "tradicional" en el método getUserName(), this tendrá el valor del objeto `nameObj`.

```
const nameObj = {
  name: "Alfredo",
  getUserName: function () {
    return () => console.log(this)
  }
}
const inside = nameObj.getUserName()

inside() 

//{name: 'Alfredo', ..}
```

O con este ejemplo, donde la función de flecha del método `setInterval` se está ejecutando en el contexto de la instancia count.

```
function IncreaseCount(count) {
  this.count = count
  setInterval(() => {
    console.log(this.count += 1)
  }, 1000);
}

const count = new IncreaseCount(30)

//31
//32
//...
```

A diferencia de este caso donde se utiliza una función "tradicional" dentro del método setInterval() y como esta se ejecuta en el ámbito global, la salida no es la esperada.

```
function IncreaseCount(count) {
  this.count = count
  setInterval(function () {
    console.log(this.count)
  }, 1000);
}


const count = new IncreaseCount(30)

// undefined
```
***

Como te habrás dado cuenta las funciones de flecha no es solo una sintaxis mas corta sino que su comportamiento es diferente a una función tradicional.

Algunas consideraciones.

- No utilices funciones de flecha en métodos de objeto.
- No utilices funciones de flecha como constructores. 
- No utilices funciones de flecha con los métodos call, apply o bind.
- Las funciones de flecha no tienen una propiedad prototype.

Espero este post haya aclarado tus dudas sobre como funciona `this` en JavaScript y las funciones de flecha.

Tu feedback es de mucha ayuda para mi 🙏

Conectemos 😎
https://twitter.com/JairDevep
https://www.linkedin.com/in/alfredo-moscoso-desarrollador-frontend/

¡Nos vemos pronto! 👊