The 5 most transformative JavaScript features from ES8

Last updated on June 20, 2024
The 5 most transformative JavaScript features from ES8

ES8 was packed with valuable features that completely transformed the way we write JavaScript.

Code became cleaner, shorter, and easier to write.

Let's check them out and see the ones you missed.

1. Trailing commas

Trailing commas used to cause a syntax error before ES8!

❌ Before:

const colors = [
  '🔴red',
  '🔵blue',
  '🟢green',
  '🟡yellow', // ❌ not allowed
];

const person = {
  name: 'Tari Ibaba',
  site: 'codingbeautydev.com' // ❌ nope
};

But this caused some problems:

But this made things inconvenient when rearranging the list:

Also we always had to add a comma to the last item to add a new one -- cluttering up git diffs:

So ES8 fixed all that:

✅ Now:

const colors = [
  '🔴red',
  '🔵blue',
  '🟢green',
  '🟡yellow', // ✅ yes
];

const person = {
  name: 'Tari Ibaba',
  site: 'codingbeautydev.com', // ✅ yes
};

The benefits they bring also made tools Prettier add them by default after formatting:

2. async / await

This was where it all started with async/await!

No more annoying nesting with then():

❌ Before:

wait().then(() => {
  console.log('WHERE ARE YOU?!😠');
});

function wait() {
  return new Promise((resolve) =>
    setTimeout(resolve, 10 * 1000)
  );
}

✅ After:

// 💡 immediately invoked function expression (IIFE)
(async () => {
  await wait();
  console.log('WHERE ARE YOU?!😠');
})();

function wait() {
  return new Promise((resolve) =>
    setTimeout(resolve, 10 * 1000)
  );
}

The difference is clear:

❌ Before:

function getSuggestion() {
  fetch('https://api.example/suggestion', {
    body: JSON.stringify,
  })
    .then((res) => {
      return res.json();
    })
    .then((data) => {
      const { suggestion } = data;
      console.log(suggestion);
    });
}

✅ After:

async function getSuggestion() {
  const res = await fetch('https://api.example/suggestion');
  const { suggestion } = await res.json();
  console.log(suggestion);
}

10 lines 3 lines.

With async/await we could finally use our native try-catch for async code:

❌ Before ES8:

startWorkout();

function startWorkout() {
  goToGym()
    .then((result) => {
      console.log(result);
    })
    .catch((err) => {
      console.log(err);
    });
}

function goToGym() {
  return new Promise((resolve, reject) => {
    if (Math.random() > 0.5) {
      reject(new Error("I'm tired today!😴"));
    }
    resolve("Let's go!🏃‍♂️👟");
  });
}

✅ Now:

startWorkout();

function startWorkout() {
  try {
    goToGym();
  } catch (err) {
    console.log(err);
  }
}

function goToGym() {
  return new Promise((resolve, reject) => {
    if (Math.random() > 0.5) {
      reject(new Error("I'm tired today!😴"));
    }
    resolve("Let's go!🏃‍♂️👟");
  });
}

3. Powerful Object static methods

Object.values()

A brilliant static method to extract all the values from an object into an array:

const person = {
  name: 'Tari Ibaba',
  site: 'codingbeautydev.com',
  color: '🔵blue',
};

const arr = Object.values(person);

// ['Tari Ibaba', 'codingbeautydev.com', '🔵blue']
console.log(arr);

Awesome for data visualization:

const fruits = [
  {
    name: 'Banana',
    pic: '🍌',
    color: 'yellow',
  },
  {
    name: 'Apple',
    pic: '🍎',
    color: 'red',
  },
];

const keys = Object.keys(fruits.at(0));
const header = keys.map((key) => `|   ${key}   |`).join('');
const rows = fruits
  .map((fruit) =>
    keys.map((key) => `|   ${fruit[key]}   |`).join('')
  )
  .join('\n');

console.log(header + '\n' + rows);

Object.entries()

Bunches each key-value pair in the object to give a list of tuples:

const person = {
  name: 'Tari Ibaba',
  site: 'codingbeautydev.com',
  color: '🔵blue',
};

const arr = Object.entries(person);

/* [
  [ 'name', 'Tari Ibaba' ],
  [ 'site', 'codingbeautydev.com' ],
  [ 'color', '🔵blue' ]
] */
console.log(arr);

Great for data transformations using both the object key and value:

Object keyed by ID list of objects:

❌ Before:

const tasks = {
  1: {
    title: '👟HIIT 30 minutes today',
    complete: false,
  },
  2: {
    name: 'Buy the backpack🎒',
    complete: true,
  },
};

const taskList = Object.keys(tasks).map((id) => ({
  id,
  ...tasks[id],
}));

console.log(taskList);

✅ Now:

// ✅ cleaner
const taskList = Object.entries(tasks).map(
  ([id, task]) => ({
    id,
    ...task,
  })
);

console.log(taskList);

4. Native string padding

On the 22nd of March 2016, the popular NPM package left-pad broke several thousands of software projects after the creator took it down as a form of protest.

It made a lot of people worried about our possible over-dependence on external modules -- even something as simple as string padding.

But luckily ES8 brought native string padding to JavaScript with the padStart and padEnd string methods:

const name = 'tari';

console.log(name.padStart(9, ' ')); // '     tari'

console.log(name.padEnd(10, '🔴')); // 'tari🔴🔴🔴'

We no longer needed to rely on yet another 3rd party dependency.

5. Object.getOwnPropertyDescriptors()

Semi-fancy name but effortless to understand.

Descriptors are properties of properties -- one of these:

  • value
  • enumerable
  • get
  • set
  • configurable
  • enumerable
const person = {
  name: 'Tari Ibaba',
  color: '🔵color',
  age: 999,
  greet: () => console.log('Hey!'),
};

console.log(
  Object.getOwnPropertyDescriptors(person)
);

Final thoughts

Overall ES8 was a significant leap for JavaScript with several features that have become essential for modern development.

Empowering you to 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