Destructuring
// Array destructuring
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// first=1, second=2, rest=[3,4,5]
// Object destructuring
const { name, age = 18 } = { name: "Alice" };
// name="Alice", age=18 (default)
// Function parameter destructuring
function display({ name, age }) {
console.log(`${name} is ${age}`);
}
display({ name: "Alice", age: 25 });Spread and Rest
// Spread — expand array/object
const a = [1, 2, 3];
const b = [...a, 4, 5]; // [1, 2, 3, 4, 5]
const obj = { ...user, role: "admin" };
// Rest — collect remaining args
function sum(...nums) {
return nums.reduce((t, n) => t + n, 0);
}
sum(1, 2, 3, 4); // 10Modules
// math.js — export
export function add(a, b) { return a + b; }
export const PI = 3.14159;
export default class Calculator { /* ... */ }
// app.js — import
import Calculator, { add, PI } from "./math.js";
import * as Math from "./math.js";Promises and async/await
// Promise
fetch("/api/users")
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
// async/await — cleaner version
async function loadUsers() {
try {
const res = await fetch("/api/users");
const data = await res.json();
console.log(data);
} catch (err) {
console.error("Failed:", err);
}
}
loadUsers();Optional Chaining and Nullish Coalescing
const user = { profile: { name: "Alice" } };
// Optional chaining — safe deep access
const city = user?.profile?.city; // undefined (no error)
const len = user?.friends?.length ?? 0; // 0
// Nullish coalescing — fallback only for null/undefined (not 0 or "")
const port = config.port ?? 3000;
const name = input ?? "Guest";Use
async/await instead of raw .then()/.catch() chains — it reads like synchronous code and try/catch handles errors naturally. Both compile to the same Promises under the hood.