Ha llegado otra actualización sobre el core del lenguaje JavaScript. En este artículo, revisaremos algunas de las mejores y más recientes funciones que vienen con ES2020.
Instalaciones
Si ustedes son desarrolladores de frontend notaran que muchas personas no piensan actualizar sus navegadores para facilitar la vida de sus desarrolladores, tendremos que usar babel para comenzar a usar funciones que no están disponibles en todos los ámbitos para los usuarios. En aras de la simplicidad podemos usar parceljs para que todo funcione lo más rápido posible.
yarn add parcel-bundler
Lamentablemente, en este momento de la historia no parece haber un ajuste funcional para ES2020. Pero si ponemos las dependencias en un archivo .babelrc y lo guardamos, Parcel debería encargarse de instalar todo.
{
"plugins": [
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-private-methods",
"@babel/plugin-syntax-bigint"
]
}
Variables de clase privada
Uno de los propósitos principales de las clases es cumplir con el correcto diseño de los componentes de nuestra aplicación. Como estas clases pueden ser utilizadas como dependencias de otros componentes lo responsable es solo exponer los métodos que van a ser utilizados, siguiendo los principios SOLID.
Ahora, al agregar un símbolo hash simple frente a nuestra variable o función, modifica el acceso de esta variable y la convierte en privada.
class Mensaje {
#contenido = "Que onda!"
getContenido() { console.log(this.#contenido) }
}
Esto progresa el lenguaje en sus capacidades de encapsulamiento de las abstracciones
Promise.allSettled
Cuando trabajamos con varias promesas, especialmente cuando dependen unas de otras, podría ser útil registrar lo que les está sucediendo a cada una para depurar errores. Con Promise.allSettled, podemos crear una nueva promesa que solo resuelva cuando todas las promesas que se le hayan asignado estén completas. Esto nos dará acceso a una matriz con algunos datos sobre cada promesa.
const p1 = new Promise((resolve, reject) => setTimeout(resolve, 100));
const p2 = new Promise((resolve, reject) => setTimeout(reject, 120));
Promise.allSettled([p1, p2]).then(resultado => console.log(resultado));
// [
// Object { status: "fulfilled", value: undefined},
// Object { status: "rejected", reason: undefined}
// ]
Operador de coalescencia null
¿que?
Yo le hubiera puesto un mejor nombre, pero les prometo que ese es el oficial, vean la documentación.
Básicamente se trata de una forma de lidiar con los tipos dinámicos de javascript. Véanlo como cuando el resultado de una función puede ser entero, falso, verdadero o nulo… Y hay desarrolladores/as a l@s que esa sensación de incertidumbre los emociona mucho.
Bien en javascript existe un concepto completamente absurdo al que denominamos como valores “falsey” o “truthy”, y esencialmente es que hay tipos que podemos tratar como booleanos a pesar de que no lo sean, veamos un ejemplo practico antes de ES2020
let persona = {
perfil: {
nombre: "",
edad: 0
}
};
console.log(persona.perfil.nombre || "Juan Topo"); // Juan Topo
console.log(persona.perfil.edad || 18); // 18
Si en este caso persona era un recién nacido que aun no ha sido bautizado, nos interesa entonces que el nombre este vacío y que la edad si sea 0.
Pero a javascript tus conceptos mundanos de la realidad no le importan, y para el interprete nombre y edad evalúan ambos a “false“, “null” o “undefined” o todo al mismo tiempo y el operador || viene al rescate y hace que se impriman los valores por defecto, a pesar de que estén correctos y si existan.
Bien ES2020 introduce un nuevo operador, y añadimos otro “workaround” mas a la larga lista de workarounds en javascript.
console.log(person.profile.name ?? "Juan Topo"); // ""
console.log(person.profile.age ?? 18); // 0
Con el operador de coalescencia tenemos la oportunidad de que al menos si no es undefined o null, no lo trate como false y hacer nuestra vida complicadamente mas fácil.
Podrán notar que esta característica no me gusto 🙂 yo hubiera creado el concepto de anotar objetos para que funcionen como nos funciona.
Operador optional chaining
Finalmente llega a javascript el operador de encadenado opcional (en buen castellano).
Si alguna vez han tenido contacto con swift, pues este funciona igual que en swift.
let persona = {};
console.log(persona.perfil.nombre ?? "Juan Topo"); // persona.perfil is undefined
console.log(persona?.perfil?.nombre ?? "Juan Topo");
console.log(persona?.perfil?.edad ?? 18);
y de alguna manera después de todos esos signos de interrogación finalmente todo converge a sus valores por defecto.
BigInt
No entraremos en los detalles técnicos, pero debido a cómo JavaScript maneja los números, cuando crecen lo suficiente, las cosas comienzan a ponerse un poco inestables. El número más grande que JavaScript puede manejar es 2 ^ 53, que podemos ver con MAX_SAFE_INTEGER.
const max = Number.MAX_SAFE_INTEGER;
console.log(max); // 9007199254740991
Cualquier cosa por encima de eso y las cosas comienzan a ponerse un poco raras …
console.log(max + 1); // 9007199254740992
console.log(max + 2); // 9007199254740992
console.log(max + 3); // 9007199254740994
console.log(Math.pow(2, 53) == Math.pow(2, 53) + 1); // true
Podemos solucionar esto con el nuevo tipo de datos BigInt. Al poner la letra “n” al final del número, podemos comenzar a usar e interactuar con números increíblemente grandes. No podemos mezclar números estándar con números BigInt, por lo que cualquier cálculo matemático también deberá realizarse con BigInts.
const bigNum = 10000000000000000000000000000n;
console.log(bigNum * 2n); // 20000000000000000000000000000n