Recientemente, el encadenamiento opcional y el valor de atributo predeterminado ( fusión nula ) se han movido al último y cuarto paso del proceso TC39.
En la práctica, esto significa que estas y otras innovaciones se convertirán en parte del estándar de JavaScript ya en este 2020. Los consideraremos en este artículo.
Puede rastrear el soporte del navegador aquí ("características 2020") - aprox. perev.
El uso de expresiones regulares globales o fijas, cuando necesita capturar múltiples grupos en la misma línea, puede no ser trivial.
String.prototype.match no devuelve grupos capturados en presencia de un indicador global, y sin él solo puede obtener la primera coincidencia completa con la plantilla y su grupo.
Un ejemplo:
let regexp = /t(e)(st(\d?))/g; let str = 'test1test2'; const results = str.match(regexp); console.log(results);
Resultado con bandera "g"
El resultado sin la bandera "g"El uso de String.prototype.matchAll garantiza que se devuelvan todas las coincidencias y sus grupos.
Un ejemplo:
let regexp = /t(e)(st(\d?))/g; let str = 'test1test2'; let array = [...str.matchAll(regexp)]; console.log(array);
Resultado:
Antes de BigInt, el valor más grande representado por Number era 2⁵³-1 (MAX_SAFE_INTEGER). JavaScript ahora tendrá una primitiva que puede exceder el límite.
Puede crear un BigInt agregando 'n' a un número o usando la función BigInt ().
Un ejemplo:
let bigInt = 4n console.log(bigInt * bigInt)
- BigInt no es equivalente a Number , pero se puede lanzar a este último.
- Al realizar operaciones como la división, el resultado se redondeará al entero más cercano.
- No se puede usar con Number sin tipo casting.
Intentando agregar BigInt con un número ...
let bigInt = 4n + 2 console.log(bigInt)
... resulta en una excepción:
Acceder a objetos globales en el mundo de JavaScript siempre ha sido un dolor de cabeza. Debe estar familiarizado con la sintaxis específica para el entorno, lo que crea dificultades innecesarias al escribir código portátil y hace que sea necesario usar algo como getGlobal.
Un ejemplo:
var getGlobal = function () { if (typeof self !== 'undefined') { return self; } if (typeof window !== 'undefined') { return window; } if (typeof global !== 'undefined') { return global; } throw new Error('no global object found'); }; var globals = getGlobal();
Con el advenimiento de globalThis, puede dejar de pensar en el entorno y unificar los objetos globales.
Un ejemplo:
globalThis.someFunction = () => 'hello' console.log(globalThis.someFunction())
Supongamos que tiene algunas promesas y desea hacer algo después de que se hayan completado (no importa si tiene éxito o no). Promise.allSettled es para este mismo propósito.
Un ejemplo:
const fulfilledPromise = Promise.resolve("success"); const rejectedPromise = Promise.reject("error") const promises = [fulfilledPromise, rejectedPromise]; Promise.allSettled(promises). then((results) => results.forEach((result) => console.log(result)));
Resultado:
¿Desea cargar un módulo en tiempo de ejecución, dependiendo de una condición específica? Ahora se puede hacer sin bibliotecas de terceros.
Es suficiente llamar a la función de importación , que devolverá la promesa.
Un ejemplo:
import("some_module") .then(module => { module.doSomething(); }) .catch(err => { console.error(err.message); });
A diferencia de la importación estática, donde debe especificar el nombre del módulo explícitamente, durante la importación dinámica puede, por ejemplo, pasar una plantilla a la función.
Ejemplo usando una plantilla:
import(`${some_module}.js`) .then(module => { module.doSomething(); }) .catch(err => { console.error(err.message); });
Cuando necesita obtener un atributo o valor predeterminado, si es nulo o no está definido , usualmente usamos el operador '||'.
Antes de la fusión nula:
const response = someResponse.properties.mayBeUndefined || 'Response';
Imagine, sin embargo, que un atributo tiene un valor "falso".
El problema de usar '||':
const someResponse = {properties: { mayBeUndefined: ''}} const response = someResponse.properties.mayBeUndefined || 'Response'; console.log(response)
Resultado:
Este es un comportamiento indeseable. En este caso, necesitábamos un valor de atributo, no un valor predeterminado.
Con Nullish coalescing este problema no será. El valor predeterminado se devolverá solo para atributos nulos o indefinidos .
Usando la fusión nula:
const someResponse = {properties: { mayBeUndefined: ''}} const response = someResponse.properties.mayBeUndefined ?? 'Response'; console.log(response)
Resultado:
Para acceder al sub-atributo, debemos asegurarnos de que el atributo anterior exista. Hasta ahora, la existencia de cada uno de los sobreatributos debe verificarse manualmente.
Antes del encadenamiento opcional:
const someObj = { property: 'prop', otherProperty: { name: 'prop2' } }; const property = someObj.NotOtherProperty ? someObj.NotOtherProperty.name: undefined; console.log(property);
Con el advenimiento del encadenamiento opcional , puede usar el operador '?.' para acceso opcional a sub-atributos. El siguiente código es equivalente al código anterior.
Usando encadenamiento opcional:
const someObj = { property: 'prop', otherProperty: { name: 'prop2' } }; const property = someObj.NotOtherProperty?.name; console.log(property);
El encadenamiento opcional hace que el código sea mucho más limpio, especialmente si hay muchos atributos en la cadena.
Conclusión
Puede intentar ejecutar ejemplos de un artículo en la consola: algunos de ellos ya están implementados en las últimas versiones de los navegadores, es probable que otros se implementen muy pronto. De una forma u otra, ya es posible comenzar a relacionarse con las posibilidades del artículo como parte del lenguaje 2020.