Innovaciones de ES2020 que realmente me gustan

JavaScript se ha desarrollado muy rápido en los últimos años. Esto es especialmente cierto para el período posterior al lanzamiento del estándar ES6 en 2015. Desde entonces, han aparecido muchas características excelentes en el lenguaje. Se han propuesto muchas novedades para su inclusión en el estándar ES2020. Ya se ha formado una lista final de características, cuya aparición se puede esperar en el estándar después de su aprobación. Esta es una buena noticia para todos los entusiastas de JS. El autor del artículo, cuya traducción publicamos hoy, dice que entre estas oportunidades hay aquellas con las que está especialmente satisfecho. Antes de que aparecieran, era mucho más difícil para él escribir código en situaciones en las que son aplicables. Según él, si hubieran aparecido en el idioma antes, le habrían ahorrado mucho tiempo y esfuerzo.





Cadenas opcionales


El encadenamiento opcional es, para mí personalmente, una de las características más interesantes del estándar ES2020. He escrito muchos programas en los que esta característica sería extremadamente útil. 

Las cadenas opcionales le permiten organizar el acceso seguro a propiedades de objetos profundamente incrustadas sin la necesidad de verificar la existencia de cada uno de ellos. Eche un vistazo a cómo funciona esta característica.

Primero, mire el código que tuvo que escribirse antes del advenimiento de las cadenas opcionales.

▍ Código antes de la aparición de cadenas opcionales


const user = {
   firstName:"Joseph",
   lastName:"Kuruvilla",
   age:38,
   address:{
      number:"239",
      street:"Ludwig Lane",
      city:"Chennai",
      zip:"600028",
   prop1:{
    prop2:{
     prop3:{
      prop4:{
       value:'sample'
      }
     }
    }
   }
   }
}
if(user && user.address){
 console.log(user.address.zip);
 //600028
}
if(user && user.address && user.address.prop1 && user.address.prop1.prop2 && user.address.prop1.prop2.prop3 && user.address.prop1.prop2.prop3.prop4){
 console.log(user.address.prop1.prop2.prop3.prop4.value);
 //sample
}
//    
console.log(user.address.prop102.po);
//Error

Como puede ver, para evitar la ocurrencia de errores, parece Cannot read property 'po' of undefinedque es necesario, en cada nivel de anidamiento, verificar las propiedades para su existencia. Con un aumento en la profundidad de anidamiento de entidades, el número de propiedades marcadas también aumenta. Esto significa que el programador mismo tiene que escribir código que lo proteja de las propiedades que, cuando se accede, pueden encontrarse con los valores de nullo undefined.

▍ Código después de la aparición de cadenas opcionales


Escribir código como el que acabamos de revisar lo hizo mucho más fácil con el advenimiento de cadenas opcionales. Para organizar un trabajo seguro con propiedades de objetos profundamente incrustadas, es suficiente usar el operador ?.. Nos ahorra la necesidad de verificar independientemente los valores en nully undefined.

Así es como se ve:

const user = {
   firstName:"Joseph",
   lastName:"Kuruvilla",
   age:38,
   address:{
      number:"239",
      street:"Ludwig Lane",
      city:"Chennai",
      zip:"600028",
   prop1:{
    prop2:{
     prop3:{
      prop4:{
       value:'sample'
      }
     }
    }
   }
   }
}
console.log(user?.address?.zip);
//600028
console.log(user?.address?.prop1?.prop2?.prop3?.prop4?.value);
//sample
//    
console.log(user?.address?.prop102?.po);
//undefined

Bueno, ¿no está bien? Gracias a esta innovación, ES2020 hizo posible deshacerse de una gran cantidad de líneas de código.

Validar solo valores nulos e indefinidos


Verificar los valores solo en nully undefined(Nullish Coalescing) es una de esas características que realmente me deleitaron incluso cuando las posibilidades estaban en la etapa de propuesta. A menudo me encontré con la necesidad de escribir funciones especializadas para realizar las verificaciones adecuadas.

Se sabe que JavaScript tiene significados "falsos" y "verdaderos". Ahora podemos decir que se les agregaron valores "cero". Estos valores incluyen nully undefined. Con términos de JavaScript de "falsa" son cadenas vacías, el número 0, los valores undefined, null, false, NaN. Es decir, por ejemplo, una cierta expresión para verificar el valor de "falsedad" funcionará en una cadena vacía y en el valorundefinedy mucho más sobre qué. Y la expresión para verificar el valor de si es "cero" devolverá truesolo para nully undefined. Tal vez esta oportunidad no te parezca tan maravillosa personalmente, pero, de hecho, es muy, muy importante.

Veamos algunos ejemplos.

▍ El código hasta la capacidad de verificar valores solo en valores nulos e indefinidos


Recientemente, estaba trabajando en un proyecto en el que necesitaba implementar la funcionalidad de cambiar entre temas claros y oscuros. Al mismo tiempo, tuve que verificar el estado del control, averiguar si corresponde al valor de trueo false. Si el usuario no estableció ningún valor, por defecto, debería ser igual true. Así es como resolví este problema antes de la posibilidad de verificar valores solo en nully undefined:

const darkModePreference1 = true
const darkModePreference2 = false
const darkModePreference3 = undefined
const darkModePreference4 = null
const getUserDarkModePreference = (darkModePreference) => {
  if (darkModePreference || darkModePreference === false) {
    return darkModePreference
  }
  return true
}
getUserDarkModePreference(darkModePreference1) 
// true
getUserDarkModePreference(darkModePreference2) 
// false
getUserDarkModePreference(darkModePreference3) 
// true
getUserDarkModePreference(darkModePreference4) 
// true

▍ Código después de la posibilidad de verificar valores solo en valores nulos e indefinidos


Una vez que esta característica ha aparecido en el idioma de verificación nully undefinedoperador suficiente ??. Puede prescindir de una declaración condicional if:

const darkModePreference1 = true
const darkModePreference2 = false
const darkModePreference3 = undefined
const darkModePreference4 = null
const getUserDarkModePreference = (darkModePreference) => {
  return darkModePreference ?? true;
}
getUserDarkModePreference(darkModePreference1) 
// true
getUserDarkModePreference(darkModePreference2) 
// false
getUserDarkModePreference(darkModePreference3) 
// true
getUserDarkModePreference(darkModePreference4) 
// true

Aquí sucede lo siguiente: si la variable darkModePreferencecontiene un valor "cero", se devuelve el valor true. Esto hace que sea más fácil escribir código, es compacto y fácil de entender.

Importaciones dinámicas


Las importaciones dinámicas contribuyen a un rendimiento de la aplicación más eficiente. Esta tecnología le permite importar archivos JS dinámicamente, en forma de módulos, sin necesidad de herramientas adicionales. Además, si el módulo no es necesario, entonces no se importa. Antes del ES2020, los módulos se importaban independientemente de si la aplicación los usaba o no.

Por ejemplo, supongamos que necesitamos implementar la funcionalidad de cargar un determinado archivo en formato PDF.

Considere, como siempre, las viejas y nuevas opciones para resolver este problema.

▍ Código antes del soporte para importaciones dinámicas


Según la situación real, podemos esperar que la capacidad de descargar materiales en formato PDF no sea utilizada por todos los visitantes de la página. Pero el módulo correspondiente, de todos modos, debe importarse al código. Esto significa que el módulo, sea necesario o no, se cargará cuando se cargue la página.

import { exportAsPdf } from './export-as-pdf.js'
const exportPdfButton = document.querySelector('.exportPdfBtn');
exportPdfButton.addEventListener('click', exportAsPdf);

Esto crea una carga adicional en el sistema, que se puede facilitar mediante el uso de la carga diferida de los módulos. Esto se puede hacer con la ayuda de la tecnología de separación de código, que está disponible en el paquete web o en otros cargadores de módulos (y su uso en sí mismo significa un desperdicio de una cierta cantidad de recursos del sistema).

Pero ahora, gracias al ES2020, tenemos una forma estándar de cargar módulos dinámicamente, lo que nos permite prescindir de los paquetes.

▍ Código después de la aparición de soporte para importaciones dinámicas


const exportPdfButton = document.querySelector('.exportPdfBtn');
exportPdfButton.addEventListener('click', () => {
  import('./export-as-pdf.js')
    .then(module => {
      module.exportAsPdf()
    })
    .catch(err => {
      //      -  
    })
})

Como puede ver, ahora puede organizar la carga diferida de módulos cargando solo cuando se necesita el módulo apropiado. Esto reduce la carga del sistema y aumenta la velocidad de carga de la página.

Promesa de construcción.


Si necesita realizar alguna acción solo si todas las promesas se han resuelto satisfactoriamente, puede usar el método Promise.all(). Es cierto que este método tiene un inconveniente. El método arrojará un error si se rechaza al menos una promesa que se le haya pasado. Esto significa que la acción necesaria no se realizará hasta que todas las promesas se resuelvan con éxito.

Puede que no necesites esto. Quizás el siguiente escenario le convenga: “El resultado no es importante para mí. Necesito que el código se ejecute después de completar todas las promesas ". En este caso, el método es útil para usted Promise.allSettled(). La promesa correspondiente se resuelve con éxito solo después de completar otras promesas. No importa si han funcionado con éxito o sin éxito.

▍ Código usando la construcción Promise.all


const PromiseArray = [
    Promise.resolve(100),
    Promise.reject(null),
    Promise.resolve("Data release"),
    Promise.reject(new Error('Something went wrong'))];
Promise.all(PromiseArray)
  .then(data => console.log('all resolved! here are the resolve values:', data))
  .catch(err => console.log('got rejected! reason:', err))
//got rejected! reason: null

Aparentemente, Promise.allda un error después del rechazo de una de las promesas transferidas.

▍ Código que usa la construcción Promise.allSettled


const PromiseArray = [
    Promise.resolve(100),
    Promise.reject(null),
    Promise.resolve("Data release"),
    Promise.reject(new Error('Something went wrong'))];
Promise.allSettled(PromiseArray).then(res =>{
console.log(res);
}).catch(err => console.log(err));
//[
//{status: "fulfilled", value: 100},
//{status: "rejected", reason: null},
//{status: "fulfilled", value: "Data release"},
//{status: "rejected", reason: Error: Something went wrong ...}
//]

Y aquí, aunque algunas de las promesas se rechazan, Promise.allSettleddevuelve los resultados emitidos por todas las promesas que se le transfieren.

Otras características notables


▍ Tipo de datos BigInt


El nuevo tipo de datos le BigIntpermite trabajar con números cuya longitud excede la longitud de los números con los que podría trabajar en JavaScript antes de que apareciera ( pow(2,53)-1). Es cierto que este tipo de datos no es compatible con versiones anteriores del idioma anterior. El estándar IEEE 754, que es la base para trabajar con números en JavaScript, no admite los números con los que es posible trabajar.BigInt

Method Método String.prototype.matchAll


El método String.prototype.matchAll()está relacionado con expresiones regulares. Devuelve un iterador, lo que le permite trabajar con todas las coincidencias encontradas en una cadena utilizando una expresión regular , incluidos los grupos .

▍ Propiedad global globalThis


La propiedad global globalThiscontiene una referencia al objeto global correspondiente al entorno en el que se ejecuta el código. En el navegador, el objeto global está representado por el objeto window. En Node.js, este es un objeto global. En los trabajadores web, este es un objeto self.

¿Qué innovaciones te gustan más del ES2020?


All Articles