advanced
Step 15 of 20
ES6+ Features
JavaScript Programming
ES6+ Features
ECMAScript 2015 (ES6) and subsequent annual releases have transformed JavaScript from a quirky scripting language into a modern, powerful programming language. These features include modules for code organization, Map and Set data structures, symbols for unique identifiers, iterators and generators, and many syntax improvements. Understanding these features is essential for reading and writing modern JavaScript code, as they are used extensively in all major frameworks and libraries.
Modules (import/export)
// Named exports (math.js)
export function add(a, b) { return a + b; }
export function subtract(a, b) { return a - b; }
export const PI = 3.14159;
// Default export (User.js)
export default class User {
constructor(name) { this.name = name; }
}
// Importing
import User from "./User.js"; // Default import
import { add, subtract, PI } from "./math.js"; // Named imports
import { add as sum } from "./math.js"; // Renamed import
import * as math from "./math.js"; // Namespace import
// Dynamic import (code splitting)
async function loadModule() {
const { default: Chart } = await import("./chart.js");
const chart = new Chart();
}
// In HTML:
// <script type="module" src="app.js"></script>
Map and Set
// Map — key-value pairs with any type as key
const userRoles = new Map();
userRoles.set("alice", "admin");
userRoles.set("bob", "user");
userRoles.set(42, "system"); // Numbers as keys
userRoles.set(true, "flag"); // Booleans as keys
console.log(userRoles.get("alice")); // "admin"
console.log(userRoles.has("bob")); // true
console.log(userRoles.size); // 4
userRoles.delete("bob");
for (const [key, value] of userRoles) {
console.log(`${key}: ${value}`);
}
// Set — collection of unique values
const uniqueIds = new Set([1, 2, 3, 2, 1]);
console.log(uniqueIds); // Set(3) {1, 2, 3}
uniqueIds.add(4);
uniqueIds.delete(1);
console.log(uniqueIds.has(2)); // true
// Practical: remove duplicates from array
const numbers = [1, 2, 2, 3, 3, 3, 4];
const unique = [...new Set(numbers)];
console.log(unique); // [1, 2, 3, 4]
// WeakMap and WeakSet — allow garbage collection of keys
const cache = new WeakMap();
let element = document.querySelector(".box");
cache.set(element, { clicks: 0 });
// When element is removed from DOM and no other references exist,
// the WeakMap entry is automatically garbage collected
Iterators and Generators
// Custom iterable
class Range {
constructor(start, end) {
this.start = start;
this.end = end;
}
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
return {
next() {
if (current <= end) {
return { value: current++, done: false };
}
return { done: true };
}
};
}
}
for (const num of new Range(1, 5)) {
console.log(num); // 1, 2, 3, 4, 5
}
// Generator function
function* fibonacci() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const fib = fibonacci();
console.log(fib.next().value); // 0
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2
// Take first N values from a generator
function* take(gen, n) {
for (let i = 0; i < n; i++) {
const { value, done } = gen.next();
if (done) return;
yield value;
}
}
console.log([...take(fibonacci(), 8)]);
// [0, 1, 1, 2, 3, 5, 8, 13]
Other Modern Features
// Logical assignment (ES2021)
let a = null;
a ??= "default"; // a = a ?? "default" → "default"
let b = "";
b ||= "fallback"; // b = b || "fallback" → "fallback"
let c = 5;
c &&= c * 2; // c = c && (c * 2) → 10
// Array.at() (ES2022) — negative indexing
const arr = [1, 2, 3, 4, 5];
console.log(arr.at(-1)); // 5
console.log(arr.at(-2)); // 4
// Object.hasOwn() (ES2022) — better than hasOwnProperty
console.log(Object.hasOwn({ x: 1 }, "x")); // true
// structuredClone (deep copy)
const original = { a: 1, b: { c: 2 }, d: [3, 4] };
const clone = structuredClone(original);
clone.b.c = 99;
console.log(original.b.c); // 2 (unchanged — deep copy)
// Top-level await (ES2022, in modules)
// const data = await fetch("/api/config").then(r => r.json());
Pro tip: UseMapinstead of plain objects when you need non-string keys, frequent additions/deletions, or need to know the size. UseSetwhenever you need a collection of unique values. Both have better performance than objects for large datasets with frequent lookups.
Key Takeaways
- ES6 modules (
import/export) are the standard for code organization in modern JavaScript. Mapsupports any key type and maintains insertion order;Setstores unique values efficiently.- Generators (
function*) produce values lazily withyield, enabling memory-efficient iteration. - Use
structuredClone()for deep copying objects instead ofJSON.parse(JSON.stringify()). - Logical assignment operators (
??=,||=,&&=) provide concise patterns for default values.