Destructuring
// Object destructuring
const { name, age, role = 'user' } = user;
// Array destructuring
const [first, , third] = [1, 2, 3];
// Rename
const { name: userName } = user;
// Nested
const { address: { city } } = user;
Spread & Rest
// Spread
const merged = { ...obj1, ...obj2 };
const combined = [...arr1, ...arr2];
const copy = { ...original };
// Rest
function sum(...nums) { return nums.reduce((a,b) => a+b); }
const { id, ...rest } = user;
Async/Await
async function fetchUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error('Not found');
return await res.json();
} catch (err) {
console.error(err);
}
}
// Parallel
const [users, posts] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
]);
Optional Chaining & Nullish Coalescing
// Optional chaining (?.)
user?.address?.city // undefined if any is null/undefined
arr?.[0] // Safe array access
fn?.() // Safe function call
// Nullish coalescing (??)
value ?? 'default' // 'default' only if null/undefined
// vs OR (||)
value || 'default' // 'default' if falsy (0, '', false)
Modules
// Named exports
export const PI = 3.14;
export function add(a, b) { return a + b; }
// Default export
export default class User { }
// Import
import User, { PI, add } from './utils.js';
Other Modern Features
// Object.entries / fromEntries
Object.entries({ a: 1, b: 2 }) // [['a',1],['b',2]]
Object.fromEntries([['a',1]]) // { a: 1 }
// structuredClone (deep copy)
const deep = structuredClone(original);
// Top-level await (ES2022)
const data = await fetch('/api').then(r => r.json());
// Array grouping (ES2024)
Object.groupBy(users, u => u.role);