No me malentiendan, aprendí mucho en la facultad. La materia que nos mostró algo de JavaScript (Desarrollo de Aplicaciones Web) fue una de la que muchos compañeros se enamoraron, sin ella no sabría jugar con el DOM, no sabría qué es Ajax, fundamentos de php, etc.
Es de esperar que en un curso no intensivo de 6 meses haya poco tiempo para adentrarse en detalles y truquitos de cada lenguaje. El lado positivo es que todavía se cuenta con el resto de una vida para aprenderlos. A continuación mencionaré algunos features que aprendí en el trabajo y me ayudaron mucho.
1. No es necesario sumar cadenas
Bueno, este apartado será corto. Dudaba si designarle todo un subtítulo a las Template literals (o template strings), pero no podía dejar de lado a uno de mis trucos favoritos de ES6+. Estas dos líneas son equivalentes:
'Bienvenido ' + nombre + ', son las ' + (new Date().getHours() + 1) + ' horas'; `Bienvenido ${nombre}, son las ${new Date().getHours() + 1} horas`;
Al usar acentos graves `
se pueden agregar expresiones dentro de un ${}
, haciendo más bonita la concatenación de cadenas y expresiones.
2. ¿A dónde apuntan esas flechas?
La primera vez que vi un símbolo de “igual” junto al “mayor que” creí que era un operador lógico. Leía y releía los =>
pero nada cobraba sentido. Afortunadamente encontré un video explicando que eso es una función flecha, y desde ese entonces no dejo de usar tan conveniente notación
Sintaxis
// Función anónima function(<argumentos>) { <cuerpo> } // Función flecha (<argumentos>) => { <cuerpo> }
La sintaxis de una función flecha es muy parecida a la de una función anónima. A la izquierda de la flecha se declaran los argumentos, y a su derecha el cuerpo. Sin embargo, la función flecha tiene un poco más de azúcar sintáctica:
- Paréntesis opcionales: Si la función flecha recibe un solo argumento que no se desestructura, se pueden omitir los paréntesis del argumento. Es decir, estas dos líneas serían equivalentes:
(<argumento>) => { <cuerpo> } <argumento> => { <cuerpo> }
- Retorno implícito: Si el cuerpo de la función flecha solo consta de retornar una expresión, eliminar los corchetes hará que el
return
sea implícito. Es decir, estas dos líneas serían equivalentes:(<argumentos>) => { return <expresión> } (<argumentos>) => <expresión>
Por ejemplo: se tiene un arreglo con números y se desea saber cuáles son mayores a 3. Usemos al método Array.prototype.filter()
, que crea un nuevo array con todos los elementos que cumplan la condición implementada por la función dada (Copypasteado de MDN).
const numbers = [5, 8, 1, 0, 10, -4]; const usingFunction = numbers.filter(function(number){ return number > 3; }); const usingArrow = numbers.filter(number => number > 3); // Tanto usingFunction como usingArrow serán [5, 8, 10]
Más que un sustituto de function
Voy a plantear un problema antes de decir dónde entran las =>
. Dentro de un método de un objeto se quiere llamar a una promesa y se desea almacenar, en el mismo objeto, algún valor que diga si la promesa se cumplió o no. Por motivos de simplicidad, la promesa en cuestión se llamará somePromise y no diremos qué hace.
const obj = { promiseSuccessful: false, someMethod() { somePromise().then(function() { this.promiseSuccessful = true; }); } }; obj.someMethod();
Uno podría pensar que el valor de obj.promiseSuccessful
sea true
si la promesa es exitosa, pero la manera en que this
funciona hace que este no sea el caso, porque el this
dentro de la función anónima apunta a un this global en lugar de a obj
.
Conozco dos soluciones. Una es no usar this
dentro de la función anónima.
// ... someMethod() { const self = this; somePromise().then(function() { self.promiseSuccessful = true; }); } // ...
La otra solución es usar una función flecha. La característica más distintiva de este tipo de funciones es que su this
apunta al mismo this
donde fue declarada.
// ... someMethod() { somePromise().then(() => { this.promiseSuccessful = true; }); } // ...
En este ejemplo, la función flecha fue declarada dentro de someMethod. Como el this
dentro de someMethod apunta a obj
, el this
dentro de la función flecha también apuntará a obj
.
¿Cuándo no usarlas?
Si al crear un objeto se usan funciones flecha para declarar sus métodos, el this
de tales métodos no va a apuntar al objeto, sino al this
del lugar donde se creó. Por ejemplo: las siguientes líneas tienen un problema similar al que teníamos inicialmente.
const obj = { promiseSuccessful: false, someMethod: () => { somePromise().then(() => { this.promiseSuccessful = true; }); } };
Debido al uso de =>
al declarar someMethod, el this
hace referencia al lugar donde se creó obj
, no al mismo obj
.

3. Expandiendo la idea de clave-valor
Cuando empecé a programar en JavaScript me llamó mucho la atención que los objetos aquí no son instancias de una clase. Los veía como sacos que permiten agregar y quitar cosas a lo desgraciado y sin privacidad. Sigo viéndolos de esa forma, pero ahora sé que pueden tener un par de reglas más.
Este apartado no es para hablar de los objetos en sí, sino una parte fundamental de ellos: las propiedades.
const persona = { nombre: 'Esteban Dido' };
El objeto anterior representa a una persona y su nombre. No nos fijaremos en el objeto en sí, sino de su propiedad “nombre“. Tal propiedad tiene las siguientes características:
- Guarda un valor (
value
). En este caso, el valor es ‘Esteban Dido’. - Se le puede asignar otro valor (
writable
): Más adelante, alguien podría cambiarle su nombre. - Se puede configurar (
configurable
): Nada impide que más adelante alguien elimine nombre o modifique sus descriptores (en breve diremos qué es eso). - Aparece al enumerar las propiedades (
enumerable
): Esto quiere decir que los métodos que usen las propiedades de persona, como JSON.stringify() u Object.keys(), también incluyen a “nombre”.
Estas características y un par más, son los descriptores de una propiedad. La forma de modificar los descriptores de una propiedad es con Object.defineProperty()
, un método muy especial que recibe 3 argumentos:
- El objeto al cual se le va a agregar o configurar la propiedad.
- La clave de la propiedad.
- Un objeto con sus descriptores.
Si quisiéramos definir la propiedad “nombre” de manera explícita, haríamos lo siguiente:
const persona = {}; Object.defineProperty( persona, // Objeto a modificar 'nombre', // Clave de la propiedad { // Descriptores value: 'Esteban Dido', writable: true, configurable: true, enumerable: true } );
Propiedades semi ocultas
Lo que me inspiró a hablar de descriptores en este artículo fue enumerable
, pues me parece el más interesante de todos.
Si quiero que persona tenga la propiedad secreto pero no quiero que esa propiedad aparezca en el resultado de JSON.stringify(persona)
, puedo definir secreto como no enumerable.
const persona = { nombre: 'Esteban Dido' }; Object.defineProperty(persona, 'secreto', { value: 'Robo chicles del Oxxo', enumerable: false }); JSON.stringify(persona); // '{"nombre":"Esteban Dido"}' persona.secreto; // 'Robo chicles del Oxxo'
Anécdota: En una ocasión quería guardar (en formato JSON) un arreglo de objetos, pero cierta dependencia requería que esos objetos tengan un valor que no me interesaba almacenar. El mayor problema era que los objetos tenían estructuras diferentes, así que no podía simplemente eliminar ese valor. Después de no poder implementar una solución complicada le pedí ayuda a un amigo, quien me habló de Object.defineProperty()
. No podía creer que sea posible configurar una propiedad.
Para terminar…
Hay muchos conceptos y features que Programadores Senior deben dominar, y estoy seguro de no conocer ni un cuarto. Saber usar un lenguaje no lo es todo, también hay que estar enterado de cosas como modularidad, buenas prácticas, principios SOLID, etc. A veces me siento un poco abrumado por tantos conceptos, pero una parte importante de ser programador es estar aprendiendo siempre, pues es natural no saber todo. Para concluir, no puedo sino alentarles a seguir ampliando su base de conocimiento.
- Design patterns in Node.js: A practical guide – LogRocket Blog.
- Jake Archibald: In The Loop – JSConf.Asia – YouTube.
- 6 Things Your Junior Devs Don’t Tell You – YouTube.
Para comentar debe estar registrado.