The 7 most transformative JavaScript features from ES10

Last updated on March 08, 2024
The 7 most transformative JavaScript features from ES10

JavaScript has come a long way in the past 10 years with brand new feature upgrades in each one.

Still remember when we created classes like this?

function Car(make, model) {
  this.make = make;
  this.model = model;
}

// And had to join strings like this
Car.prototype.drive = function() {
  console.log("Vroom! This " + this.make +
    " " + this.model + " is driving!");
};

Yeah, a lot has changed!

Let's take a look at the 7 most significant features that arrived in ES10 (2019); and see the ones you missed.

1. Modularization on the fly: Dynamic imports

The ES10 year was the awesome year when import could now act as function, like require(). An async function.

Keeping imports at the top-level was no longer a must; We could now easily resolve the module's name at compile time.

Loading modules optionally and only when absolutely needed for high-flying performance...

async function asyncFunc() {
  if (condition) {
    const giganticModule = await import('./gigantic-module');
  }
}

Loading modules based on user or variable input...

import minimist from 'minimist';

const argv = minimist(process.argv.slice(2));

viewModule(argv.name);

async function viewModule(name) {
  const module = await import(name);
  console.log(Object.keys(module));
}

It's also great for using ES modules that no longer support require():

// ❌ require() of ES modules is not supported
const chalk = require('chalk');
console.log(chalk.blue('Coding Beauty'));

(async () => {
  // ✅ Runs successfully
  const chalk = (await import('chalk')).default;
  console.log(chalk.blue('Coding Beauty'));
})();

2. Flattening the curve

flat() and flatMap() gave much cleaner ways to easily flatten multidimensional arrays.

Eradicating the need for painful array-looping flattening code:

const colorSwatches = [
  'cream🟡',
  ['scarlet🔴', 'cherry🔴'],
  ['blue🔷', ['sky blue🟦', 'navy blue🔵']],
];

// Default depth of 1
console.log(colorSwatches.flat());
// ['cream🟡', 'scarlet🔴', 'cherry🔴', 'blue🔷',
//   ['sky blue🟦', 'navy blue🔵']]

console.log(colorSwatches.flat(2));
// ['cream🟡', 'scarlet🔴', 'cherry🔴', 'blue🔷',
//   'sky blue🟦', 'navy blue🔵']

flatMap() is as good as calling map(), then flat(1):

const colorSwatches = [
  'cream🟡',
  ['scarlet🔴', 'cherry🔴'],
  ['blue🔷', ['sky blue🟦', 'navy blue🔵']],
];

// map to get only the emoji
console.log(
  colorSwatches.flatMap((color) =>
    Array.isArray(color) ? color : color.slice(-2)
  )
);
// [ '🟡', 'cherry🔴', 'blue🔷', [ 'sky blue🟦', 'navy blue🔵' ] ]

3. Transform arrays to objects

ES10 was also when Object.fromEntries() arrived on the JavaScript scene.

Quickly convert list of key-value pairs to equivalent key-value object:

const entries = [
  ['name', 'The Flash⚡'],
  ['realName', 'Barry Allen'],
  ['lightningColor', 'yellow🟡'],
  ['suitColor', 'red🔴'],
];

console.log(Object.fromEntries(entries));
/**
{
  name: 'The Flash⚡',
  realName: 'Barry Allen',
  lightningColor: 'yellow🟡',
  suitColor: 'red🔴'
}
*/

4. Clean up your strings with precisions

trimStart() and trimEnd().

Before now everyone was using trim from NPM - Happily adding 3.35KB to the project...

Even now:

But slowly losing popularity to .trim().

Then Array trim() came along, then trimStart() and trimEnd().

const fruits = '   pineapple🍍   ';

console.log(fruits.trimStart()); // 'pineapple🍍   '

console.log(fruits.trimEnd()); // '   pineapple🍍'

console.log(fruits.trim()); // 'pineapple🍍'

5. Catching errors without the baggage

With the new optional catch binding, you now safely omit the catch block's error argument when you had nothing to do with it:

// ❌ Before ES10
try {
  iMayExplodeAnyMomentNow();
} catch (err) {
  // Or else error
}

// ✅
try {
  iMayExplodeAnyMomentNow();
} catch {}

6. Sorting without surprise

Stable Array sort.

Previously when sorting an array there was absolutely no way we could guarantee the arrangement of the equal elements.

But in the post-ES10 JS code here, we are 100% sure that react always comes before vue always comes before angular.

const geniusPortfolio = [
  {
    tool: 'javascript',
    years: 2000,
  },
  { tool: 'react', years: 1000 },
  { tool: 'vue', years: 1000 },
  { tool: 'angular', years: 1000 },
  { tool: 'assembly', years: 7000 },
];

const sortedDesc = geniusPortfolio.sort((a, b) => {
  return b.years - a.years;
});

const sortedAsc = geniusPortfolio.sort((a, b) => {
  return a.years - b.years;
});

7. Go big or go home: BigInts

The name BigInt gives it purpose away: For loading up on unbelievably humongous integer values:

const bigInt =
  240389470239846028947208942742089724204872042n;

const bigInt2 = BigInt(
  '34028974029641089471947861048917649816048962'
);

console.log(typeof bigInt);
console.log(bigInt);

console.log(typeof bigInt2);
console.log(bigInt2);

console.log(bigInt * bigInt2);

Because normal integers can't:

// ✖️ Stored as double
const normalInt = 240389470239846028947208942742089724204872042;

const normalInt2 = 34028974029641089471947861048917649816048962;

console.log(typeof normalInt);
console.log(normalInt);

console.log(typeof normalInt2);
console.log(normalInt2);

// ✖️ Precision lost
console.log(normalInt * normalInt2);

Final thoughts

ES10 marked a significant leap forward for JavaScript with several features that have become essential for modern development.

Use them write cleaner code with greater conciseness, expressiveness, and clarity.

Coding Beauty Assistant logo

Try Coding Beauty AI Assistant for VS Code

Meet the new intelligent assistant: tailored to optimize your work efficiency with lightning-fast code completions, intuitive AI chat + web search, reliable human expert help, and more.

See also