Top 10 Changes in ECMAScript 2024

1. BigInt methods

ECMAScript 2024 brought in many new methods to the BigInt object to make it easier to work with arbitrary-precision integers. Some key additions include:

This makes BigInt behave more like regular Numbers when doing bitwise operations.

let big = 0b1101n; 
let reinterpreted = BigInt.asIntN(4, big); // reinterprets as signed 4-bit integer
console.log(reinterpreted); // 5n

2. toSorted() method on arrays

JavaScript arrays now have a handy toSorted() method to conveniently sort arrays in-place.

let arr = [5, 3, 4, 1, 2];
arr.toSorted((a, b) => a - b);
console.log(arr); // [1, 2, 3, 4, 5]

This avoids the need to manually call sort() and pass in a compare function.

3. Top-level await

await can now be used at the top-level of modules, allowing asynchronous initialization through promises.

// module.js
let data = await initialize();

export function someFunc() {
  return data;
}

This cleans up initialization logic compared to async wrappers or immediately invoked async functions.

4. Import assertions

ECMAScript modules now support import assertions with import type {..} and import.meta.d.ts to specify types of imports.

import type { User } from './users.js';

import.meta.d.ts;

This avoids issues with TypeScript needing duplicate declarations and enables tools to infer types.

5. Top-level this

A new global globalThis was introduced as a standardized way to refer to the global context object.

function someFunc() {
  return globalThis;  
}

This provides a clear way to refer to the global without depending on this which may not point to the global in all cases.

6. Try/catch statements

try blocks can now include declarations, allowing scoping of variables to the block.

try {
  let response = await fetch('/data');
} catch {
  console.log('Failed to fetch data');
}

This matches the intuitive behavior expected by developers coming from other languages.

7. Promise.allSettled

A new Promise.allSettled method resolves all promises whether fulfilled or rejected.

let results = await Promise.allSettled([
  Promise.resolve(1),
  Promise.reject(new Error()),
  Promise.resolve(3)  
]);

This is useful for situations where the outcome of each promise is needed regardless of another's result.

8. WeakRefs and FinalizationRegistry

New WeakRef and FinalizationRegistry objects allow weakly holding objects without preventing garbage collection.

let obj = {name: 'John'};
let weakref = new WeakRef(obj);

let registry = new FinalizationRegistry(obj => {
  // obj cleaned up
});

This enables new GC patterns like finalizers and reference counting without performance degradation.

9. import.meta

Modules now have a standardized import.meta object containing metadata relevant to the module.

export function getsSource() {
  return import.meta.url;
}

This provides an interop and extension point for bundlers and module systems to surface information to modules.

10. Assertion improvements

assert module got upgrades including distinguishing failed from thrown assertions, ignoring messages, and new predicates.

assert.doesNotReject(fn);
assert.ifError(err);

This enhances capabilities for test frameworks and other validation use cases.