
Modern JavaScript ES6+ Features
ES6 (ECMAScript 2015) and subsequent versions introduced numerous features that have modernized JavaScript development.
Arrow Functions
Arrow functions provide a shorter syntax and lexical this binding:
// Before ES6
const add = function(a, b) {
return a + b;
};
// ES6+ Arrow function
const add = (a, b) => a + b;
// With multiple lines
const multiply = (a, b) => {
const result = a * b;
return result;
};
Template Literals
Enhanced string literals with interpolation and multi-line support:
const name = "John";
const age = 25;
// Before
const greeting = "Hello, " + name + "! You are " + age + " years old.";
// ES6+
const greeting = `Hello, ${name}! You are ${age} years old.`;
Destructuring
Extract values from arrays and objects:
// Array destructuring
const [first, second, third] = [1, 2, 3];
// Object destructuring
const user = { name: "John", age: 25, email: "john@example.com" };
const { name, email } = user;
// Default values
const { name, age = 18 } = user;
Spread and Rest Operators
Spread expands arrays/objects, rest collects remaining elements:
// Spread operator
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
// Rest operator
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
Promises and Async/Await
Better handling of asynchronous operations:
// Promises
function fetchData() {
return fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
}
// Async/Await
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
Modules
ES6 module system for better code organization:
// utils.js
export const helper = () => {
return "I'm a helper function";
};
export const PI = 3.14159;
// main.js
import { helper, PI } from './utils.js';
import * as utils from './utils.js';
console.log(helper()); // "I'm a helper function"
console.log(utils.PI); // 3.14159
Classes
Syntactical sugar over prototype-based inheritance:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, I'm ${this.name}`;
}
static create(name, age) {
return new Person(name, age);
}
}
class Developer extends Person {
constructor(name, age, language) {
super(name, age);
this.language = language;
}
code() {
return `${this.name} is coding in ${this.language}`;
}
}
Optional Chaining and Nullish Coalescing
Safe property access and default values:
// Optional chaining
const user = {
profile: {
name: "John"
}
};
const name = user?.profile?.name; // "John"
const email = user?.profile?.email; // undefined
// Nullish coalescing
const value = null ?? "default"; // "default"
const count = 0 ?? 10; // 0
Map and Set
New data structures for better performance:
// Map - key-value pairs where keys can be objects
const map = new Map();
map.set("key1", "value1");
map.set({ name: "John" }, "person");
// Set - unique values only
const set = new Set([1, 2, 2, 3, 4, 4]);
console.log(set); // Set { 1, 2, 3, 4 }
Modern JavaScript Best Practices
- Use const and let instead of var
- Prefer arrow functions for cleaner syntax
- Use template literals for string interpolation
- Leverage destructuring for cleaner code
- Handle async operations with async/await
- Use modules for better code organization
These ES6+ features have made JavaScript more powerful, readable, and maintainable. Understanding and using them effectively will significantly improve your development experience and code quality.