Back to Blog

JavaScript ES2024: New Features Every Developer Should Know

Anand Jaiswal
January 25, 2024
4 min read
JavaScriptES2024Web DevelopmentProgramming

JavaScript ES2024: New Features Every Developer Should Know

JavaScript continues to evolve with exciting new features in ES2024. Let's explore the most important additions that will enhance your development experience.

Array.fromAsync()

Create arrays from async iterables:

async function* asyncGenerator() {
  yield 1;
  yield 2;
  yield 3;
}

const array = await Array.fromAsync(asyncGenerator());
console.log(array); // [1, 2, 3]

// With mapping function
const doubled = await Array.fromAsync(asyncGenerator(), x => x * 2);
console.log(doubled); // [2, 4, 6]

Object.groupBy()

Group array elements by a key:

const people = [
  { name: 'Alice', age: 25, department: 'Engineering' },
  { name: 'Bob', age: 30, department: 'Marketing' },
  { name: 'Charlie', age: 35, department: 'Engineering' },
  { name: 'Diana', age: 28, department: 'Marketing' }
];

const byDepartment = Object.groupBy(people, person => person.department);
console.log(byDepartment);
// {
//   Engineering: [{ name: 'Alice', ... }, { name: 'Charlie', ... }],
//   Marketing: [{ name: 'Bob', ... }, { name: 'Diana', ... }]
// }

Map.groupBy()

Similar to Object.groupBy but returns a Map:

const byAge = Map.groupBy(people, person => 
  person.age < 30 ? 'young' : 'experienced'
);
console.log(byAge);
// Map {
//   'young' => [{ name: 'Alice', ... }, { name: 'Diana', ... }],
//   'experienced' => [{ name: 'Bob', ... }, { name: 'Charlie', ... }]
// }

Promise.withResolvers()

Get resolver and rejector functions:

function createPromiseWithTimeout(ms) {
  const { promise, resolve, reject } = Promise.withResolvers();
  
  setTimeout(() => {
    resolve('Timeout completed');
  }, ms);
  
  return { promise, resolve, reject };
}

const { promise, resolve } = createPromiseWithTimeout(1000);
// You can call resolve() from outside when needed

String.prototype.isWellFormed()

Check if string is well-formed Unicode:

const validString = "Hello, 世界!";
const invalidString = "\uD800"; // Lone surrogate

console.log(validString.isWellFormed()); // true
console.log(invalidString.isWellFormed()); // false

String.prototype.toWellFormed()

Convert to well-formed Unicode string:

const malformedString = "Hello\uD800World";
const wellFormed = malformedString.toWellFormed();
console.log(wellFormed); // "Hello�World" (replacement character)

Atomics.waitAsync()

Non-blocking wait for SharedArrayBuffer:

const sab = new SharedArrayBuffer(1024);
const int32 = new Int32Array(sab);

// Non-blocking wait
const result = Atomics.waitAsync(int32, 0, 0);
if (result.async) {
  result.value.then(() => {
    console.log('Value changed!');
  });
}

RegExp v Flag

Enhanced Unicode support:

// Unicode property escapes
const regex = /\p{Script=Latin}/v;
console.log(regex.test('Hello')); // true

// Set notation
const emojiRegex = /[\p{Emoji}--\p{ASCII}]/v;
console.log(emojiRegex.test('😀')); // true
console.log(emojiRegex.test('A')); // false

Practical Examples

Data Processing Pipeline

async function processUserData(users) {
  // Group users by status
  const grouped = Object.groupBy(users, user => user.status);
  
  // Process each group asynchronously
  const processed = await Array.fromAsync(
    Object.entries(grouped),
    async ([status, userList]) => {
      const processedUsers = await Promise.all(
        userList.map(user => processUser(user))
      );
      return { status, users: processedUsers };
    }
  );
  
  return processed;
}

Safe String Handling

function sanitizeUserInput(input) {
  if (!input.isWellFormed()) {
    input = input.toWellFormed();
  }
  
  // Additional sanitization
  return input.trim().toLowerCase();
}

Async Iterator Processing

async function* fetchDataPages(url) {
  let page = 1;
  let hasMore = true;
  
  while (hasMore) {
    const response = await fetch(`${url}?page=${page}`);
    const data = await response.json();
    
    yield data.items;
    hasMore = data.hasMore;
    page++;
  }
}

// Convert to array
const allData = await Array.fromAsync(
  fetchDataPages('/api/data'),
  page => page.map(item => ({ ...item, processed: true }))
);

Browser Support

Most ES2024 features are supported in:

  • Chrome 117+
  • Firefox 119+
  • Safari 17+
  • Node.js 21+

Always check compatibility for production use.

Migration Tips

  1. Use Polyfills: For older browsers, consider polyfills
  2. Gradual Adoption: Start with non-critical features
  3. TypeScript Support: Update to latest TypeScript version
  4. Testing: Ensure comprehensive test coverage

Conclusion

ES2024 brings powerful new features that enhance JavaScript's capabilities:

  • Array.fromAsync() simplifies async iteration
  • Object.groupBy() makes data grouping elegant
  • Promise.withResolvers() provides better promise control
  • String methods improve Unicode handling
  • RegExp v flag enhances pattern matching

These features will make your JavaScript code more expressive and efficient. Start experimenting with them in your projects today!


Stay updated with the latest JavaScript features and best practices for modern web development.

About the Author

Anand Jaiswal is a full-stack developer passionate about creating exceptional digital experiences and sharing knowledge with the community.