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:
- Use transpilers like Babel to convert ES6+ code to ES5
- Check compatibility tables at caniuse.com
- Use polyfills for missing features
| 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
- Use
const by default, let when reassignment is needed
- Prefer arrow functions for callbacks and anonymous functions
- Use destructuring to extract values from objects and arrays
- Leverage async/await for cleaner asynchronous code
- Organize code using modules for better maintainability
- Use template literals for string interpolation and multi-line strings