Javascript y las mejoras en ES11 (ES2020) – Parte 7

Las nuevas features de Javascript ES11 (ES2020)

Con esta nueva entrada ampliamos el tutorial de Javascript y su mejoras, añadiendo las últimas features que se han incluido en la última versión de Javascript ES11 (ES2020).

Debemos recordar que estas features puede que no se encuentren disponibles en todos los navegadores, pero usando usando Babel en su versión 7.8 o superior (versión actual 7.11.0) podremos usarlas sin problemas.

A continuación veremos las nuevas features que se han incluido:

  • Operador Nullish Coalescing

    • El nuevo operador ?? lógico, es parecido al operador OR salvo que este solo comprueba verdaderos valores nulos (null y undefined).
    • console.log(undefined ?? 'resultado'); // resultado
      console.log(null ?? 'resultado');      // resultado
      console.log(NaN ?? 'resultado');       // NaN
      console.log('' ?? 'resultado');        // 
      console.log(false ?? 'resultado');     // false
      console.log(0 ?? 'resultado');         // 0
      
      console.log(undefined || 'resultado'); // resultado
      console.log(null || 'resultado');      // resultado
      console.log(NaN || 'resultado');       // resultado
      console.log('' || 'resultado');        // resultado
      console.log(false || 'resultado');     // resultado
      console.log(0 || 'resultado');         // resultado
  • Optional Chaining

    • Usando esta nueva sintaxis podemos acceder a cualquier propiedad y cualquier nivel de un objeto sin tener que preocuparnos, si existe o no.
    • En el caso de no existir nos devuelve undefined, ademas esta sintaxis nos permite también aplicarlas en funciones y arrays.
    • const data = {
          nombre: 'aaaa',
          estudios: [
          {
              curso: 'qqq',
              nota: 10
          },
          {
              curso: 'www',
              nota: 9
          }
          ],
          getNombre() {
              return this.nombre;
          },
          experiencia: ['pppp', 'oooo', 'iiii'],
      };
      
      console.log(data?.nombre);                   // aaaa
      console.log(data?.nombre2);                  // undefined
      console.log(data?.estudios?.[0]);            // { curso: "qqq", nota: 10 }
      console.log(data?.estudios?.[3]);            // undefined
      console.log(data?.estudios2?.[0]);           // undefined
      console.log(data?.estudios?.[0]?.curso);     // qqq
      console.log(data?.estudios?.[0]?.nota);      // 10
      console.log(data?.estudios?.[0]?.nota2);     // undefined
      console.log(data?.getNombre?.());            // aaaa
      console.log(data?.getNombre2?.());           // undefined
      console.log(data?.experiencia?.[0]);         // pppp
      console.log(data?.experiencia?.[10]);        // undefined
      console.log(data?.experiencia2?.[0]);        // undefined
  • globalThis

    • Cuando necesitamos acceder al objeto this nos podemos encontrar en la siguientes situaciones dependiendo del entorno:
      • Nnavegador: window es el objeto this global.
      • Nodejs: global es el objeto this global.
      • Web worker: self es el objeto this global.
    • Con globalThis ya tenemos una forma estandarizada de acceder al objeto this global.
    • console.log(globalThis === window); // true
  • String.prototype.matchAll

      • Este nuevo método nos devuelve un iterador con todos los resultados coincidentes en una cadena de texto usando una expresión regular.
      • console.log([...'patólogo, patóloga, pan, patógeno, pares'.matchAll(/pat/g)]);
        
        /*
        [Array(1), Array(1), Array(1)]
        [
           ["pat", index: 0, input: "patólogo, patóloga, pan, patógeno, pares", groups: undefined],
           ["pat", index: 10, input: "patólogo, patóloga, pan, patógeno, pares", groups: undefined],
           ["pat", index: 25, input: "patólogo, patóloga, pan, patógeno, pares", groups: undefined]
        ]
        */
  • BigInt

    • Esta nueva feature nos permite superar el limite que tiene actualmente Javascript para manejar valores enteros.
    • El límite actual de un número entero es 9007199254740991, pero ahora añadiendo una n al final del número entero podemos crear números enteros más grandes.
    • let nMax = Number.MAX_SAFE_INTEGER;
      console.log(nMax); // 9007199254740991
      nMax++;
      console.log(nMax); // 9007199254740991
      
      let nMore = 9007199254740991n;
      console.log(nMore); // 9007199254740991n
      nMore++;
      console.log(nMore); // 9007199254740992n
      nMore++;
      console.log(nMore); // 9007199254740993n
      nMore++;
      console.log(nMore); // 9007199254740994n
      nMore++;
      console.log(nMore); // 9007199254740995n
      nMore++;
      console.log(nMore); // 9007199254740996n
      nMore++;
      console.log(nMore); // 9007199254740997n
      
      
  • Promise.allSettled

    • Actualmente Javascript tiene el método Promise.all que funciona igual que Promise.allSettled pero con una pequeña diferencia:
      • Promise.all: Si falla alguna de las promesas, la ejecución fallaría inmediatamente con el valor de la promesa que fallo descartando el resto de las demás promesas hayan sido o no cumplidas.
      • Promise.allSettled: Con este método todas las promesas se ejecutaran independientemente de si su estado es resolved o rejected, devolviendo en un array con el resultado de cada una de las promesas.
    • // Promise.all
      const promise1 = Promise.resolve(1);
      const promise2 = Promise.resolve(2);
      const promise3 = Promise.reject(3);
      const arrayPromise = [promise1, promise2, promise3];
      
      Promise.all(arrayPromise).then(result => console.log('OK', result)).catch(err => console.log('ERROR', err));
      /*
          ERROR 3
          Script snippet %2340:1 Promise {<fulfilled>: undefined}
      */
      
      Promise.allSettled(arrayPromise).then(result => console.log('OK', result)).catch(err => console.log('ERROR', err));
      /*
          OK
          0: {status: "fulfilled", value: 1}
          1: {status: "fulfilled", value: 2}
          2: {status: "rejected", reason: 3}
      */
  • Imports dinámicos

    • Los imports dinámicos nos permiten importar módulos dinámicamente de forma nativa, tal como hace Webpack o Babel.
    • import('./tools.js').then(module => {
          module.capitalize();
      });
      
      (async () => {
          const module = await('./tools.js');
          module.capitalize();
      })();
  • Import.meta

    • El objeto import.meta nos permite acceder a los metadatos de un módulo.
    • <script src="./tools.js" type="module"></script>
      console.log(import.meta);  // { url: "file:///www/libs/tools.js" }

       

Esta nueva revisión nos ha traído algunas mejoras que facilitan el trabajo y que la comunidad frontend echaba en falta.