JavaScript ES6+ Features Guide - Modern JavaScript Development

Introduction: ES6 (ECMAScript 2015) introduced significant improvements to JavaScript, making it more powerful and easier to write. This guide covers the most important ES6+ features every developer should know.

1. Arrow Functions

Arrow functions provide a more concise syntax for writing function expressions and handle 'this' binding differently:

// Traditional function
const add = function(a, b) {
  return a + b;
};

// Arrow function
const add = (a, b) => a + b;

// With single parameter (parentheses optional)
const square = x => x * x;

// With multiple parameters
const multiply = (x, y) => x * y;

// With block statement
const log = (message) => {
  console.log(message);
  return message;
};
Output:
console.log(add(5, 3)); // 8
console.log(square(4)); // 16
console.log(multiply(3, 4)); // 12

2. Template Literals

Template literals allow for multi-line strings and string interpolation:

// Traditional string concatenation
const name = 'John';
const age = 30;
const message = 'Hello, my name is ' + name + ' and I am ' + age + ' years old.';

// Template literal
const templateMessage = `Hello, my name is ${name} and I am ${age} years old.`;

// Multi-line strings
const multiline = `
This is line 1
This is line 2
This is line 3
`;

// Expression interpolation
const price = 10;
const tax = 0.1;
const total = `The total cost is $${(price * (1 + tax)).toFixed(2)}.`;
Output:
console.log(templateMessage); // "Hello, my name is John and I am 30 years old."
console.log(multiline); // Multi-line string with actual line breaks
console.log(total); // "The total cost is $11.00."

3. Destructuring Assignment

Destructuring allows unpacking values from arrays or properties from objects into distinct variables:

// Array destructuring
const colors = ['red', 'green', 'blue'];
const [first, second, third] = colors;
console.log(first); // 'red'

// Object destructuring
const person = { name: 'Alice', age: 25, city: 'New York' };
const { name, age, city } = person;
console.log(name); // 'Alice'

// Function parameter destructuring
const displayPerson = ({ name, age }) => {
  console.log(`${name} is ${age} years old`);
};

// Array destructuring with rest
const [firstColor, ...remainingColors] = colors;
console.log(remainingColors); // ['green', 'blue']

// Default values
const { title = 'Unknown', author = 'Anonymous' } = { title: 'ES6 Guide' };
console.log(title); // 'ES6 Guide'
console.log(author); // 'Anonymous'

4. Let and Const

New variable declarations with block scope instead of function scope:

// var has function scope
function varExample() {
  for (var i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 100); // logs 3, 3, 3
  }
}

// let has block scope
function letExample() {
  for (let i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 100); // logs 0, 1, 2
  }
}

// const for constants
const PI = 3.14159;
const user = { name: 'John', age: 30 };
// user = { name: 'Jane' }; // Error!
user.age = 31; // OK - object is mutable

5. Classes

ES6 introduced class syntax for creating objects and dealing with inheritance:

class Animal {
  constructor(name, species) {
    this.name = name;
    this.species = species;
  }

  makeSound() {
    console.log(`${this.name} makes a sound`);
  }

  static getKingdom() {
    return 'Animalia';
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name, 'Canine'); // Call parent constructor
    this.breed = breed;
  }

  makeSound() {
    console.log(`${this.name} barks`);
  }
}

const myDog = new Dog('Buddy', 'Golden Retriever');
myDog.makeSound(); // 'Buddy barks'
console.log(Animal.getKingdom()); // 'Animalia'

6. Modules

ES6 introduced a module system for organizing code:

// math.js
export const PI = 3.14159;

export const add = (a, b) => a + b;

export const multiply = (a, b) => a * b;

// Default export
export default function subtract(a, b) {
  return a - b;
}

// main.js
import subtract, { PI, add, multiply } from './math.js';
// or
import * as math from './math.js';

console.log(add(5, 3)); // 8
console.log(subtract(10, 4)); // 6

7. Promises

Promises provide a better way to handle asynchronous operations:

// Creating a promise
const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = Math.random() > 0.5;
      if (success) {
        resolve('Data fetched successfully!');
      } else {
        reject('Failed to fetch data');
      }
    }, 1000);
  });
};

// Using the promise
fetchData()
  .then(result => console.log(result))
  .catch(error => console.error(error));

// Chaining promises
fetchData()
  .then(result => result.toUpperCase())
  .then(upperResult => console.log(upperResult))
  .catch(error => console.error(error));

8. Async/Await

Async/await provides a cleaner syntax for working with promises:

// Async function
async function getData() {
  try {
    const result = await fetchData();
    console.log(result);
    return result;
  } catch (error) {
    console.error('Error:', error);
  }
}

// Using async/await
getData();

// Multiple async operations
async function processMultiple() {
  try {
    const result1 = await fetchData();
    const result2 = await fetchData();
    console.log(result1, result2);
  } catch (error) {
    console.error('Error:', error);
  }
}

// Parallel execution
async function parallelExecution() {
  try {
    const [result1, result2] = await Promise.all([
      fetchData(),
      fetchData()
    ]);
    console.log(result1, result2);
  } catch (error) {
    console.error('Error:', error);
  }
}

9. Additional ES6+ Features

Other important features introduced in ES6 and later:

// Default parameters
const greet = (name = 'World') => `Hello, ${name}!`;

// Spread operator
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]

const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }

// Rest parameters
const sum = (...numbers) => numbers.reduce((a, b) => a + b, 0);

// Map and Set
const map = new Map();
map.set('key', 'value');

const set = new Set([1, 2, 3, 3]); // [1, 2, 3]

// For...of loops
for (const item of [1, 2, 3]) {
  console.log(item);
}

10. Browser Compatibility

ES6+ features are supported in all modern browsers. For older browsers:

Feature Browser Support
Arrow Functions Chrome 45+, Firefox 38+, Safari 10+, Edge 13+
Classes Chrome 45+, Firefox 45+, Safari 9+, Edge 13+
Promises Chrome 32+, Firefox 29+, Safari 8+, Edge 12+
Modules Chrome 61+, Firefox 60+, Safari 10.1+, Edge 16+
Important: While ES6+ features make JavaScript more powerful, always consider your target audience's browser support requirements and use appropriate build tools when necessary.

11. Best Practices

  1. Use const by default, let when reassignment is needed
  2. Prefer arrow functions for callbacks and anonymous functions
  3. Use destructuring to extract values from objects and arrays
  4. Leverage async/await for cleaner asynchronous code
  5. Organize code using modules for better maintainability
  6. Use template literals for string interpolation and multi-line strings
Home