ES2022: Las 7 nuevas y flamantes funciones

ES2022

7 nuevas funciones enviadas con ES2022

7 nuevas funciones ES2022… ¡que los desarrolladores deberían estar entusiasmados!


Como sabrá, desde ES6 en 2015, TC39 de Ecma International lanza una nueva versión de ECMAScript cada año. ES2022 es la 13.ª edición de la especificación del lenguaje ECMAScript.

Esta nueva iteración viene con su propio lote de nuevas características: ¡revisémoslas!

1. Espera de nivel superior

La await de nivel superior permite que los módulos actúen como grandes funciones asíncronas.

Con la await de nivel superior, los módulos ECMAScript (ESM) pueden esperar recursos, lo que hace que otros módulos que los importan esperen antes de comenzar a evaluar su cuerpo.

// say this is my-apple.js
await Promise.resolve('🦥') // '🦥'

Casos de uso

¿Cuándo tendría sentido tener un módulo que espera a que se cargue una operación asíncrona?

Ruta de dependencia dinámica

const strings = await import(`/i18n/${navigator.language}`);

Esto permite que los módulos usen valores de tiempo de ejecución para determinar las dependencias. Esto es útil para cosas como divisiones de desarrollo/producción, internacionalización, divisiones de entorno, etc.

Inicialización de recursos

const connection = await dbConnector();

Esto permite que los Módulos representen recursos y también que produzcan errores en los casos en que el Módulo nunca se podrá utilizar.

Respaldos de dependencia

let jQuery;
try {
jQuery = await import('https://cdn-a.com/jQuery');
} catch {
jQuery = await import('https://cdn-b.com/jQuery');
}

2. Método .at() en todos los indexables incorporados

Actualmente, para acceder a un valor desde el final de un objeto indexable, la práctica común es escribir arr[arr.length - n].

Esto requiere nombrar el indexable dos veces y, además, agrega siete caracteres más para .length y es hostil a los valores anónimos.

Además, no puede usar esta técnica para capturar el último elemento del valor de retorno de una función a menos que primero lo almacene en una variable temporal. Veamos qué podemos hacer con .at():

const users = ['👷‍♀️', '🧟‍♂️', '👶', '🧝', '🙋‍♂️'];// Until today
users[users.length - 1]; // '🙋‍♂️'
users[1]; // '🧟‍♂️'
users[1000]; // undefined// With the .at() method;
users.at(-1); // '🙋‍♂️'
users.at(1); // '🧟‍♂️'
users.at(1000); // undefined
["🍍", "🍏"].at(0); // "🍍"

3. Una más accesible hasOwnProperty: Object.hasOwn

Si no posee directamente todas las propiedades definidas en un objeto, no puede estar 100 % seguro de que llamar a .hasOwnProperty() está llamando al método integrado. Veamos este ejemplo:

let object = {
  hasOwnProperty() {
    throw new Error("gotcha!")
  }
}object.hasOwnProperty("foo")
// Uncaught Error: gotcha!

Object.hasOwn comparte exactamente el mismo comportamiento que .hasOwnProperty() y se implementa como tal:

let object = { foo: false }
Object.hasOwn(object, "foo") // truelet object2 = Object.create({ foo: true })
Object.hasOwn(object2, "foo") // falselet object3 = Object.create(null)
Object.hasOwn(object3, "foo") // false

Bueno saber

ESLint tiene una regla integrada para prohibir el uso de prototipos integrados como hasOwnProperty.

4. Índices de coincidencia RegExp

ECMAScript RegExp Match Indices proporciona información adicional sobre los índices de inicio y finalización de las subcadenas capturadas en relación con el inicio de la cadena de entrada.

Veámoslo en acción:

const re1 = /a+(?<Z>z)?/d;
// indices are relative to start of the input string:
const s1 = "xaaaz";
const m1 = re1.exec(s1);
m1.indices[0][0]; // 1
m1.indices[0][1]; // 5
s1.slice(...m1.indices[0]); // "aaaz"
m1.indices[1][0]; // 4
m1.indices[1][1]; // 5
s1.slice(...m1.indices[1]); // "z"
m1.indices.groups["Z"][0]; // 4
m1.indices.groups["Z"][1]; // 5
s1.slice(...m1.indices.groups["Z"]); // "z"
// capture groups that are not matched return `undefined`:
const m2 = re1.exec("xaaay");
m2.indices[1]; // undefined
m2.indices.groups["Z"]; // undefined

Bueno saber

Por razones de rendimiento, los indices solo se agregarán al resultado si se especifica el indicador d.

5. Causa del error

Para ayudar a diagnosticar comportamientos inesperados, los errores deben complementarse con información contextual, como mensajes de error y propiedades de instancias de errores, para explicar lo que sucedió en ese momento.

Si el error se generó a partir de métodos internos profundos, es posible que el error generado no se realice de manera directa y eficiente sin un patrón de diseño de excepción adecuado.

Ahora, Error() acepta un parámetro de opciones adicional: la propiedad cause. La cause se asignará a las instancias de error como una propiedad. Esto significa que los errores se pueden encadenar sin trámites innecesarios y demasiado elaborados para envolver los errores en condiciones:

async function doJob() {
  const rawResource = await fetch('//domain/resource-a')
    .catch(err => {
      throw new Error(
        'Download raw resource failed',
        { cause: err }
      );
    });
  const jobResult = doComputationalHeavyJob(rawResource);
  await fetch(
    '//domain/upload',
    { method: 'POST', body: jobResult }
  ).catch(err => {
      throw new Error('Upload job result failed', { cause: err });
    });
}
try {
  await doJob();
} catch (e) {
  console.log(e);
  console.log('Caused by', e.cause);
}
// Error: Upload job result failed
// Caused by TypeError: Failed to fetch

6. Comprobaciones de marca ergonómicas para campos privados

Esta nueva característica propone una forma compacta de verificar si un objeto tiene un campo privado dado.

class ClassA {
  #name;
  static hasName(obj) {
    return #name in obj; //
  }
}
class ClassB {
  hello () {
    return 'Hello';
  }
}
const myClassA = new ClassA();
const myClassB = new ClassB();
ClassA.hasName(myClassA); // true;
ClassA.hasName(myClassB); // false;

Conclusión

¡Eso es todo para este ES2022! ¡Buen trabajo por llegar al final del artículo!

Como desarrollador, mantenerse al día con la evolución del lenguaje es clave para su crecimiento.

¿Cuál de esas características es la más emocionante para ti?

¡Gracias por leer!


Si le interesa, puede echar un vistazo a algunos de los otros artículos que he escrito recientemente sobre Laravel:

Recent Post