Skip to content

Commit 4196773

Browse files
author
Francisco Manuel Olmedo Bueno
committed
rambling-js-2
1 parent 72c55ee commit 4196773

File tree

4 files changed

+177
-0
lines changed

4 files changed

+177
-0
lines changed

franmolmedo/.gitkeep

Whitespace-only changes.
Loading
11.6 KB
Loading

franmolmedo/rambling-js-2/readme.md

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
![Header](images/js.png)
2+
3+
# Rambling Javascript #2: Fat arrow functions
4+
5+
Continuamos nuestro camino indagando sobre diversos aspectos de JavaScript. En este caso vamos a comentar sobre uno de los añadidos más relevantes que se hicieron con _ES6__EcmaScript 2015_). Estamos hablando de las _Fat arrow functions_. Con su uso conseguiremos un código más legible y compacto.
6+
Sin embargo, es conveniente hacer hincapié en algunos puntos que pueden pasarse de largo a la hora de trabajar con ellas. Comenzamos.
7+
8+
## Sintaxis
9+
10+
Tomaremos como base un ejemplo básico de función escrita en _ES5_. En este caso la función ```add``` tiene como argumentos dos números y nos devuelve la suma.
11+
12+
```javascript
13+
const add = function(a,b) {
14+
return a + b;
15+
}
16+
```
17+
18+
Código totalmente correcto, pero quizás un pelín verboso para lo que realmente hace, que es la suma de dos números. De ahí partimos con las _fat arrow function_. En un primer momento podemos sustituir la palabra reservada ```function``` por el símbolo siguiente ```=>```, conocido como _fat arrow_, quedando la expresión de la siguiente forma:
19+
20+
```javascript
21+
const add = (a,b) => {
22+
return a + b;
23+
}
24+
```
25+
Hemos reducido algunos caracteres, pero la mejora tampoco es demasiado sustancial. Sin embargo, podemos seguir trabajando en la expresión. El siguiente aspecto en el que podemos dar cuenta, es que nuestra función consta de una única expresión. En casos como éste, podemos igualmente quitar la palabra reservada ```return``` e, incluso, quitar las llaves delimitadora de la función. Con ello, la palabra reservada ```return``` quedaría implícita en la única expresión de la que constaría nuestra función. Por lo tanto:
26+
27+
```javascript
28+
const add = (a,b) => a + b;
29+
```
30+
31+
Creo que se intuye que extendiendo su uso conseguiremos un código más claro y limpio.
32+
33+
El siguiente ejemplo también nos permite presentar un nuevo detalle relativo a la sintaxis:
34+
35+
![Ejemplo sintaxis](images/basicExample.gif)
36+
37+
Efectivamente, también hay puntos que aclarar sobre la sintaxis relativo a los argumentos:
38+
* En funciones sin argumentos, o con dos o más, es necesario rodearlos con paréntesis:
39+
40+
```javascript
41+
const sayHelloWorld = () => 'Hello World';
42+
43+
const sayHelloWorldTwo = (place, hour) => `Hello ${place} at ${hour}`
44+
```
45+
46+
* Sin embargo, cuando tengamos un sólo argumento, los paréntesis son opcionales, tal y como hemos visto en el ejemplo previo.
47+
48+
## Uso en casos reales
49+
50+
Todo lo que se ha comentado está bien, pero realmente, y con los ejemplos vistos, tampoco parece un cambio demasiado relevante.
51+
Sin embargo, cuando nos vamos a casos un poco más realistas, es donde empezamos a observar su valía. El ejemplo más claro en el que es muy útil su uso es en los predicados que utilizamos en las funciones para tratar con colecciones.
52+
Mostramos el típico ejemplo de un array de números, y queremos extraer aquellos cuyo valor sea mayor o igual que 5:
53+
54+
```javascript
55+
const numbers = [10,2,3,4,5,8]
56+
57+
const result = numbers.filter(function(number){
58+
return number >= 5;
59+
});
60+
```
61+
62+
En este caso, utilizando _fat arrow functions_, nuestro ejemplo quedaría de la siguiente forma:
63+
64+
```javascript
65+
const numbers = [10,2,3,4,5,8]
66+
67+
const result = numbers.filter(number => number >= 5);
68+
```
69+
70+
La mejora queda clara en cuanto a legibilidad. Imaginemos su uso en callbacks, donde ayudaran, sino a reducir, sí a mejorar, el temido [callback hell](http://callbackhell.com/) en javascript.
71+
72+
## Comportamiento de ```this```
73+
74+
Todo lo comentado tiene su valor, pero donde realmente está el factor diferenciador de las fat arrow function respecto al empleo de las funciones tradicionales es en el cambio de comportamiento que ha sufrido ```this```. Cualquier persona que haya trabajado con un código JavaScript relativamente complejo, saliendo de los ejemplos básicos, habrá obtenido comportamientos no esperables de ```this```. ¿Cuántos hemos hecho uso de alguno de los siguientes _workarounds_?:
75+
* Guardarnos el contexto en una variable para poder utilizarlo en el callback. Todos hemos hecho alguna vez:
76+
77+
```javascript
78+
function test(){
79+
var self = this;
80+
callOtherFunction(function(callbackResponse){
81+
console.log(this);
82+
console.log(self);
83+
})
84+
}
85+
```
86+
87+
* Utilizar el ```bind(this)```, a la hora de definir una función.
88+
89+
Con el uso de las _fat arrow functions_ esto ya no será necesario, ya que, por defecto, ```this``` se va a referir al contexto donde la función haya sido declarada. Lo vemos con el ejemplo siguiente:
90+
91+
```javascript
92+
const testObject = {
93+
numbers: [10,20,30,40,50],
94+
title: 'Double of',
95+
double: function(){
96+
return this.numbers.map(function(number){
97+
return `${this.title} ${number} is ${2*number}`;
98+
})
99+
}
100+
}
101+
102+
console.log(testObject.double());
103+
104+
```
105+
106+
Si ejecutamos el ejemplo obtenemos lo siguiente:
107+
108+
```javascript
109+
["undefined 10 is 20", "undefined 20 is 40", "undefined 30 is 60", "undefined 40 is 80", "undefined 50 is 100"]
110+
```
111+
112+
¿Qué está ocurriendo? Pues lo que todos sabíamos de antemano, el ```this``` dentro de la función que se ejecuta en el _map_ no es el que cabría esperarse (el objeto _testObject_, sino que es el contexto global, donde, lógicamente, no está definido _title_). Esto lo resolveríamos en _ES5_ con una de las formas siguientes:
113+
114+
```javascript
115+
const testObject = {
116+
numbers: [10,20,30,40,50],
117+
title: 'Double of',
118+
double: function(){
119+
const self = this;
120+
return this.numbers.map(function(number){
121+
return `${self.title} ${number} is ${2*number}`;
122+
})
123+
}
124+
}
125+
126+
console.log(testObject.double());
127+
```
128+
129+
```javascript
130+
const testObject = {
131+
numbers: [10,20,30,40,50],
132+
title: 'Double of',
133+
double: function(){
134+
return this.numbers.map(function(number){
135+
return `${this.title} ${number} is ${2*number}`;
136+
}.bind(this));
137+
}
138+
}
139+
140+
console.log(testObject.double());
141+
```
142+
143+
Mientras que, usando _fat arrow function_, el ejemplo quedaría:
144+
145+
```javascript
146+
const testObject = {
147+
numbers: [10,20,30,40,50],
148+
title: 'Double of',
149+
double: function() {
150+
return this.numbers.map(number =>
151+
`${this.title} ${number} is ${2*number}`);
152+
}
153+
};
154+
155+
console.log(testObject.double());
156+
```
157+
158+
En todos los casos el resultado sería el esperado:
159+
160+
```javascript
161+
["Double of 10 is 20", "Double of 20 is 40", "Double of 30 is 60", "Double of 40 is 80", "Double of 50 is 100"]
162+
```
163+
164+
165+
### Conclusiones
166+
En este caso no hay mucho que comentar:
167+
* Sintaxis más sencilla.
168+
* Código más legible.
169+
* Facilidad a la hora de escribir callbacks o predicados.
170+
* Quita problemas al usar ```this```
171+
172+
Todo son ventajas.
173+
174+
En la siguiente entrega hablaremos de los operadores rest / spread y de los valores por defecto que podemos indicar a nuestras funciones.
175+
176+
## Links
177+
* [Practica ES6](http://jsbin.com/?console,output)

0 commit comments

Comments
 (0)