Modern JavaScript ES6+ Features You Should Know
JavaScript has evolved significantly with ES6 (ES2015) and beyond. Let's explore the features that make modern JavaScript more powerful and elegant.
Arrow Functions
Concise syntax for writing functions:
// Traditional function
function add(a, b) {
return a + b;
}
// Arrow function
const add = (a, b) => a + b;
// With single parameter
const square = x => x * x;
// With code block
const greet = name => {
const message = `Hello, ${name}!`;
return message;
};
Lexical this Binding
Arrow functions don't have their own this:
class Timer {
constructor() {
this.seconds = 0;
}
start() {
setInterval(() => {
this.seconds++; // 'this' refers to Timer instance
console.log(this.seconds);
}, 1000);
}
}
Destructuring
Extract values from arrays and objects:
// Array destructuring
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest); // [3, 4, 5]
// Object destructuring
const user = {
name: 'John',
age: 30,
email: 'john@example.com'
};
const { name, age } = user;
console.log(name); // 'John'
// With renaming
const { name: userName, age: userAge } = user;
// Default values
const { country = 'USA' } = user;
Function Parameters
// Destructured parameters
function displayUser({ name, age, email }) {
console.log(`${name} (${age}): ${email}`);
}
displayUser(user);
Template Literals
String interpolation and multi-line strings:
const name = 'Alice';
const age = 25;
// String interpolation
const greeting = `Hello, my name is ${name} and I'm ${age} years old.`;
// Multi-line strings
const html = `
<div class="user">
<h2>${name}</h2>
<p>Age: ${age}</p>
</div>
`;
// Expression evaluation
const price = 19.99;
const total = `Total: $${(price * 1.1).toFixed(2)}`;
Spread and Rest Operators
Spread Operator (...)
// Array spreading
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
// Object spreading
const person = { name: 'John', age: 30 };
const employee = { ...person, role: 'Developer' };
// Copy arrays/objects
const copy = [...arr1];
const clone = { ...person };
Rest Parameters
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
sum(1, 2, 3, 4, 5); // 15
Enhanced Object Literals
const name = 'Alice';
const age = 25;
// Shorthand property names
const user = { name, age };
// Method shorthand
const calculator = {
add(a, b) {
return a + b;
},
subtract(a, b) {
return a - b;
}
};
// Computed property names
const key = 'email';
const person = {
[key]: 'alice@example.com',
[`${key}Verified`]: true
};
Promises and Async/Await
Promises
function fetchUser(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id > 0) {
resolve({ id, name: 'John' });
} else {
reject(new Error('Invalid ID'));
}
}, 1000);
});
}
// Using promises
fetchUser(1)
.then(user => console.log(user))
.catch(error => console.error(error));
Async/Await
async function getUser(id) {
try {
const user = await fetchUser(id);
console.log(user);
return user;
} catch (error) {
console.error('Error:', error);
}
}
// Parallel execution
async function getAllUsers() {
const [user1, user2, user3] = await Promise.all([
fetchUser(1),
fetchUser(2),
fetchUser(3)
]);
return [user1, user2, user3];
}
Classes
Syntactic sugar for prototypal inheritance:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
introduce() {
return `Hi, I'm ${this.name}`;
}
// Getter
get birthYear() {
return new Date().getFullYear() - this.age;
}
// Setter
set fullName(value) {
const [first, last] = value.split(' ');
this.firstName = first;
this.lastName = last;
}
// Static method
static create(name, age) {
return new Person(name, age);
}
}
// Inheritance
class Developer extends Person {
constructor(name, age, language) {
super(name, age);
this.language = language;
}
code() {
return `${this.name} is coding in ${this.language}`;
}
}
Modules
Exporting
// math.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export default class Calculator {
// ...
}
Importing
// app.js
import Calculator, { PI, add } from './math.js';
// Import everything
import * as math from './math.js';
// Rename imports
import { add as sum } from './math.js';
Array Methods
const numbers = [1, 2, 3, 4, 5];
// map
const doubled = numbers.map(n => n * 2);
// filter
const evens = numbers.filter(n => n % 2 === 0);
// reduce
const sum = numbers.reduce((acc, n) => acc + n, 0);
// find
const found = numbers.find(n => n > 3);
// some & every
const hasEven = numbers.some(n => n % 2 === 0);
const allPositive = numbers.every(n => n > 0);
Optional Chaining (?.)
Safely access nested properties:
const user = {
name: 'John',
address: {
city: 'New York'
}
};
// Without optional chaining
const zip = user && user.address && user.address.zip;
// With optional chaining
const zip = user?.address?.zip;
// With function calls
const result = obj?.someMethod?.(args);
Nullish Coalescing (??)
Provide default values for null/undefined:
const value = null ?? 'default'; // 'default'
const value = 0 ?? 'default'; // 0 (not default!)
// Compare with ||
const value = 0 || 'default'; // 'default'
Best Practices
Use const by default, let when needed
const PI = 3.14159; // Won't change let counter = 0; // Will changePrefer arrow functions for callbacks
array.map(item => item * 2);Use destructuring for cleaner code
const { name, age } = user;Async/await for better readability
const data = await fetchData();Use template literals for string composition
const message = `Hello, ${name}!`;
Conclusion
These ES6+ features make JavaScript more powerful, readable, and maintainable. Incorporate them into your daily coding to write modern, clean JavaScript.
Keep learning and exploring new features as JavaScript continues to evolve! 🚀