modern-javascript-patterns by wshobson/agents
npx skills add https://github.com/wshobson/agents --skill modern-javascript-patterns掌握现代 JavaScript (ES6+) 功能、函数式编程模式以及编写简洁、可维护和高性能代码的最佳实践的综合指南。
语法和用例:
// 传统函数
function add(a, b) {
return a + b;
}
// 箭头函数
const add = (a, b) => a + b;
// 单参数(括号可选)
const double = (x) => x * 2;
// 无参数
const getRandom = () => Math.random();
// 多语句(需要花括号)
const processUser = (user) => {
const normalized = user.name.toLowerCase();
return { ...user, name: normalized };
};
// 返回对象(用括号包裹)
const createUser = (name, age) => ({ name, age });
词法 'this' 绑定:
class Counter {
constructor() {
this.count = 0;
}
// 箭头函数保留 'this' 上下文
increment = () => {
this.count++;
};
// 传统函数在回调中丢失 'this'
incrementTraditional() {
setTimeout(function () {
this.count++; // 'this' 是 undefined
}, 1000);
}
// 箭头函数保持 'this'
incrementArrow() {
setTimeout(() => {
this.count++; // 'this' 指向 Counter 实例
}, 1000);
}
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
对象解构:
const user = {
id: 1,
name: "John Doe",
email: "john@example.com",
address: {
city: "New York",
country: "USA",
},
};
// 基本解构
const { name, email } = user;
// 重命名变量
const { name: userName, email: userEmail } = user;
// 默认值
const { age = 25 } = user;
// 嵌套解构
const {
address: { city, country },
} = user;
// rest 运算符
const { id, ...userWithoutId } = user;
// 函数参数
function greet({ name, age = 18 }) {
console.log(`Hello ${name}, you are ${age}`);
}
greet(user);
数组解构:
const numbers = [1, 2, 3, 4, 5];
// 基本解构
const [first, second] = numbers;
// 跳过元素
const [, , third] = numbers;
// rest 运算符
const [head, ...tail] = numbers;
// 交换变量
let a = 1,
b = 2;
[a, b] = [b, a];
// 函数返回值
function getCoordinates() {
return [10, 20];
}
const [x, y] = getCoordinates();
// 默认值
const [one, two, three = 0] = [1, 2];
扩展运算符:
// 数组扩展
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];
// 对象扩展
const defaults = { theme: "dark", lang: "en" };
const userPrefs = { theme: "light" };
const settings = { ...defaults, ...userPrefs };
// 函数参数
const numbers = [1, 2, 3];
Math.max(...numbers);
// 复制数组/对象(浅拷贝)
const copy = [...arr1];
const objCopy = { ...user };
// 不可变地添加项
const newArr = [...arr1, 4, 5];
const newObj = { ...user, age: 30 };
剩余参数:
// 收集函数参数
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
sum(1, 2, 3, 4, 5);
// 与常规参数一起使用
function greet(greeting, ...names) {
return `${greeting} ${names.join(", ")}`;
}
greet("Hello", "John", "Jane", "Bob");
// 对象剩余
const { id, ...userData } = user;
// 数组剩余
const [first, ...rest] = [1, 2, 3, 4, 5];
// 基本用法
const name = "John";
const greeting = `Hello, ${name}!`;
// 多行字符串
const html = `
<div>
<h1>${title}</h1>
<p>${content}</p>
</div>
`;
// 表达式求值
const price = 19.99;
const total = `Total: $${(price * 1.2).toFixed(2)}`;
// 标签模板字面量
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
const value = values[i] || "";
return result + str + `<mark>${value}</mark>`;
}, "");
}
const name = "John";
const age = 30;
const html = highlight`Name: ${name}, Age: ${age}`;
// 输出: "Name: <mark>John</mark>, Age: <mark>30</mark>"
const name = "John";
const age = 30;
// 简写属性名
const user = { name, age };
// 简写方法名
const calculator = {
add(a, b) {
return a + b;
},
subtract(a, b) {
return a - b;
},
};
// 计算属性名
const field = "email";
const user = {
name: "John",
[field]: "john@example.com",
[`get${field.charAt(0).toUpperCase()}${field.slice(1)}`]() {
return this[field];
},
};
// 动态属性创建
const createUser = (name, ...props) => {
return props.reduce(
(user, [key, value]) => ({
...user,
[key]: value,
}),
{ name },
);
};
const user = createUser("John", ["age", 30], ["email", "john@example.com"]);
创建和使用 Promise:
// 创建 Promise
const fetchUser = (id) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id > 0) {
resolve({ id, name: "John" });
} else {
reject(new Error("Invalid ID"));
}
}, 1000);
});
};
// 使用 Promise
fetchUser(1)
.then((user) => console.log(user))
.catch((error) => console.error(error))
.finally(() => console.log("Done"));
// 链式调用 Promise
fetchUser(1)
.then((user) => fetchUserPosts(user.id))
.then((posts) => processPosts(posts))
.then((result) => console.log(result))
.catch((error) => console.error(error));
Promise 组合器:
// Promise.all - 等待所有 Promise
const promises = [fetchUser(1), fetchUser(2), fetchUser(3)];
Promise.all(promises)
.then((users) => console.log(users))
.catch((error) => console.error("At least one failed:", error));
// Promise.allSettled - 等待所有,无论结果如何
Promise.allSettled(promises).then((results) => {
results.forEach((result) => {
if (result.status === "fulfilled") {
console.log("Success:", result.value);
} else {
console.log("Error:", result.reason);
}
});
});
// Promise.race - 第一个完成的
Promise.race(promises)
.then((winner) => console.log("First:", winner))
.catch((error) => console.error(error));
// Promise.any - 第一个成功的
Promise.any(promises)
.then((first) => console.log("First success:", first))
.catch((error) => console.error("All failed:", error));
基本用法:
// 异步函数总是返回 Promise
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`);
const user = await response.json();
return user;
}
// 使用 try/catch 进行错误处理
async function getUserData(id) {
try {
const user = await fetchUser(id);
const posts = await fetchUserPosts(user.id);
return { user, posts };
} catch (error) {
console.error("Error fetching data:", error);
throw error;
}
}
// 顺序执行 vs 并行执行
async function sequential() {
const user1 = await fetchUser(1); // 等待
const user2 = await fetchUser(2); // 然后等待
return [user1, user2];
}
async function parallel() {
const [user1, user2] = await Promise.all([fetchUser(1), fetchUser(2)]);
return [user1, user2];
}
高级模式:
// 异步立即执行函数表达式
(async () => {
const result = await someAsyncOperation();
console.log(result);
})();
// 异步迭代
async function processUsers(userIds) {
for (const id of userIds) {
const user = await fetchUser(id);
await processUser(user);
}
}
// 顶层 await (ES2022)
const config = await fetch("/config.json").then((r) => r.json());
// 重试逻辑
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await fetch(url);
} catch (error) {
if (i === retries - 1) throw error;
await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
// 超时包装器
async function withTimeout(promise, ms) {
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error("Timeout")), ms),
);
return Promise.race([promise, timeout]);
}
Map、Filter、Reduce:
const users = [
{ id: 1, name: "John", age: 30, active: true },
{ id: 2, name: "Jane", age: 25, active: false },
{ id: 3, name: "Bob", age: 35, active: true },
];
// Map - 转换数组
const names = users.map((user) => user.name);
const upperNames = users.map((user) => user.name.toUpperCase());
// Filter - 选择元素
const activeUsers = users.filter((user) => user.active);
const adults = users.filter((user) => user.age >= 18);
// Reduce - 聚合数据
const totalAge = users.reduce((sum, user) => sum + user.age, 0);
const avgAge = totalAge / users.length;
// 按属性分组
const byActive = users.reduce((groups, user) => {
const key = user.active ? "active" : "inactive";
return {
...groups,
[key]: [...(groups[key] || []), user],
};
}, {});
// 方法链式调用
const result = users
.filter((user) => user.active)
.map((user) => user.name)
.sort()
.join(", ");
高级数组方法:
// Find - 第一个匹配元素
const user = users.find((u) => u.id === 2);
// FindIndex - 第一个匹配的索引
const index = users.findIndex((u) => u.name === "Jane");
// Some - 至少一个匹配
const hasActive = users.some((u) => u.active);
// Every - 全部匹配
const allAdults = users.every((u) => u.age >= 18);
// FlatMap - 映射并扁平化
const userTags = [
{ name: "John", tags: ["admin", "user"] },
{ name: "Jane", tags: ["user"] },
];
const allTags = userTags.flatMap((u) => u.tags);
// From - 从可迭代对象创建数组
const str = "hello";
const chars = Array.from(str);
const numbers = Array.from({ length: 5 }, (_, i) => i + 1);
// Of - 从参数创建数组
const arr = Array.of(1, 2, 3);
函数作为参数:
// 自定义 forEach
function forEach(array, callback) {
for (let i = 0; i < array.length; i++) {
callback(array[i], i, array);
}
}
// 自定义 map
function map(array, transform) {
const result = [];
for (const item of array) {
result.push(transform(item));
}
return result;
}
// 自定义 filter
function filter(array, predicate) {
const result = [];
for (const item of array) {
if (predicate(item)) {
result.push(item);
}
}
return result;
}
返回函数的函数:
// 柯里化
const multiply = (a) => (b) => a * b;
const double = multiply(2);
const triple = multiply(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
// 部分应用
function partial(fn, ...args) {
return (...moreArgs) => fn(...args, ...moreArgs);
}
const add = (a, b, c) => a + b + c;
const add5 = partial(add, 5);
console.log(add5(3, 2)); // 10
// 记忆化
function memoize(fn) {
const cache = new Map();
return (...args) => {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
return result;
};
}
const fibonacci = memoize((n) => {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
});
// 函数组合
const compose =
(...fns) =>
(x) =>
fns.reduceRight((acc, fn) => fn(acc), x);
const pipe =
(...fns) =>
(x) =>
fns.reduce((acc, fn) => fn(acc), x);
// 示例用法
const addOne = (x) => x + 1;
const double = (x) => x * 2;
const square = (x) => x * x;
const composed = compose(square, double, addOne);
console.log(composed(3)); // ((3 + 1) * 2)^2 = 64
const piped = pipe(addOne, double, square);
console.log(piped(3)); // ((3 + 1) * 2)^2 = 64
// 实际示例
const processUser = pipe(
(user) => ({ ...user, name: user.name.trim() }),
(user) => ({ ...user, email: user.email.toLowerCase() }),
(user) => ({ ...user, age: parseInt(user.age) }),
);
const user = processUser({
name: " John ",
email: "JOHN@EXAMPLE.COM",
age: "30",
});
// 不纯函数(修改输入)
function addItemImpure(cart, item) {
cart.items.push(item);
cart.total += item.price;
return cart;
}
// 纯函数(无副作用)
function addItemPure(cart, item) {
return {
...cart,
items: [...cart.items, item],
total: cart.total + item.price,
};
}
// 不可变数组操作
const numbers = [1, 2, 3, 4, 5];
// 添加到数组
const withSix = [...numbers, 6];
// 从数组移除
const withoutThree = numbers.filter((n) => n !== 3);
// 更新数组元素
const doubled = numbers.map((n) => (n === 3 ? n * 2 : n));
// 不可变对象操作
const user = { name: "John", age: 30 };
// 更新属性
const olderUser = { ...user, age: 31 };
// 添加属性
const withEmail = { ...user, email: "john@example.com" };
// 移除属性
const { age, ...withoutAge } = user;
// 深克隆(简单方法)
const deepClone = (obj) => JSON.parse(JSON.stringify(obj));
// 更好的深克隆
const structuredClone = (obj) => globalThis.structuredClone(obj);
// 类语法
class User {
// 私有字段
#password;
// 公共字段
id;
name;
// 静态字段
static count = 0;
constructor(id, name, password) {
this.id = id;
this.name = name;
this.#password = password;
User.count++;
}
// 公共方法
greet() {
return `Hello, ${this.name}`;
}
// 私有方法
#hashPassword(password) {
return `hashed_${password}`;
}
// Getter
get displayName() {
return this.name.toUpperCase();
}
// Setter
set password(newPassword) {
this.#password = this.#hashPassword(newPassword);
}
// 静态方法
static create(id, name, password) {
return new User(id, name, password);
}
}
// 继承
class Admin extends User {
constructor(id, name, password, role) {
super(id, name, password);
this.role = role;
}
greet() {
return `${super.greet()}, I'm an admin`;
}
}
// 导出
// math.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export class Calculator {
// ...
}
// 默认导出
export default function multiply(a, b) {
return a * b;
}
// 导入
// app.js
import multiply, { PI, add, Calculator } from "./math.js";
// 重命名导入
import { add as sum } from "./math.js";
// 导入全部
import * as Math from "./math.js";
// 动态导入
const module = await import("./math.js");
const { add } = await import("./math.js");
// 条件加载
if (condition) {
const module = await import("./feature.js");
module.init();
}
// 自定义迭代器
const range = {
from: 1,
to: 5,
[Symbol.iterator]() {
return {
current: this.from,
last: this.to,
next() {
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
},
};
},
};
for (const num of range) {
console.log(num); // 1, 2, 3, 4, 5
}
// 生成器函数
function* rangeGenerator(from, to) {
for (let i = from; i <= to; i++) {
yield i;
}
}
for (const num of rangeGenerator(1, 5)) {
console.log(num);
}
// 无限生成器
function* fibonacci() {
let [prev, curr] = [0, 1];
while (true) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
// 异步生成器
async function* fetchPages(url) {
let page = 1;
while (true) {
const response = await fetch(`${url}?page=${page}`);
const data = await response.json();
if (data.length === 0) break;
yield data;
page++;
}
}
for await (const page of fetchPages("/api/users")) {
console.log(page);
}
// 可选链
const user = { name: "John", address: { city: "NYC" } };
const city = user?.address?.city;
const zipCode = user?.address?.zipCode; // undefined
// 函数调用
const result = obj.method?.();
// 数组访问
const first = arr?.[0];
// 空值合并
const value = null ?? "default"; // 'default'
const value = undefined ?? "default"; // 'default'
const value = 0 ?? "default"; // 0 (不是 'default')
const value = "" ?? "default"; // '' (不是 'default')
// 逻辑赋值
let a = null;
a ??= "default"; // a = 'default'
let b = 5;
b ??= 10; // b = 5 (不变)
let obj = { count: 0 };
obj.count ||= 1; // obj.count = 1
obj.count &&= 2; // obj.count = 2
// 防抖
function debounce(fn, delay) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn(...args), delay);
};
}
const searchDebounced = debounce(search, 300);
// 节流
function throttle(fn, limit) {
let inThrottle;
return (...args) => {
if (!inThrottle) {
fn(...args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
}
const scrollThrottled = throttle(handleScroll, 100);
// 惰性求值
function* lazyMap(iterable, transform) {
for (const item of iterable) {
yield transform(item);
}
}
// 仅使用所需部分
const numbers = [1, 2, 3, 4, 5];
const doubled = lazyMap(numbers, (x) => x * 2);
const first = doubled.next().value; // 仅计算第一个值
'use strict' 用于更好的错误捕获每周安装数
6.5K
仓库
GitHub 星标数
32.3K
首次出现
2026年1月20日
安全审计
安装于
claude-code5.0K
opencode3.8K
gemini-cli3.7K
codex3.6K
cursor3.4K
github-copilot3.2K
Comprehensive guide for mastering modern JavaScript (ES6+) features, functional programming patterns, and best practices for writing clean, maintainable, and performant code.
Syntax and Use Cases:
// Traditional function
function add(a, b) {
return a + b;
}
// Arrow function
const add = (a, b) => a + b;
// Single parameter (parentheses optional)
const double = (x) => x * 2;
// No parameters
const getRandom = () => Math.random();
// Multiple statements (need curly braces)
const processUser = (user) => {
const normalized = user.name.toLowerCase();
return { ...user, name: normalized };
};
// Returning objects (wrap in parentheses)
const createUser = (name, age) => ({ name, age });
Lexical 'this' Binding:
class Counter {
constructor() {
this.count = 0;
}
// Arrow function preserves 'this' context
increment = () => {
this.count++;
};
// Traditional function loses 'this' in callbacks
incrementTraditional() {
setTimeout(function () {
this.count++; // 'this' is undefined
}, 1000);
}
// Arrow function maintains 'this'
incrementArrow() {
setTimeout(() => {
this.count++; // 'this' refers to Counter instance
}, 1000);
}
}
Object Destructuring:
const user = {
id: 1,
name: "John Doe",
email: "john@example.com",
address: {
city: "New York",
country: "USA",
},
};
// Basic destructuring
const { name, email } = user;
// Rename variables
const { name: userName, email: userEmail } = user;
// Default values
const { age = 25 } = user;
// Nested destructuring
const {
address: { city, country },
} = user;
// Rest operator
const { id, ...userWithoutId } = user;
// Function parameters
function greet({ name, age = 18 }) {
console.log(`Hello ${name}, you are ${age}`);
}
greet(user);
Array Destructuring:
const numbers = [1, 2, 3, 4, 5];
// Basic destructuring
const [first, second] = numbers;
// Skip elements
const [, , third] = numbers;
// Rest operator
const [head, ...tail] = numbers;
// Swapping variables
let a = 1,
b = 2;
[a, b] = [b, a];
// Function return values
function getCoordinates() {
return [10, 20];
}
const [x, y] = getCoordinates();
// Default values
const [one, two, three = 0] = [1, 2];
Spread Operator:
// Array spreading
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];
// Object spreading
const defaults = { theme: "dark", lang: "en" };
const userPrefs = { theme: "light" };
const settings = { ...defaults, ...userPrefs };
// Function arguments
const numbers = [1, 2, 3];
Math.max(...numbers);
// Copying arrays/objects (shallow copy)
const copy = [...arr1];
const objCopy = { ...user };
// Adding items immutably
const newArr = [...arr1, 4, 5];
const newObj = { ...user, age: 30 };
Rest Parameters:
// Collect function arguments
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
sum(1, 2, 3, 4, 5);
// With regular parameters
function greet(greeting, ...names) {
return `${greeting} ${names.join(", ")}`;
}
greet("Hello", "John", "Jane", "Bob");
// Object rest
const { id, ...userData } = user;
// Array rest
const [first, ...rest] = [1, 2, 3, 4, 5];
// Basic usage
const name = "John";
const greeting = `Hello, ${name}!`;
// Multi-line strings
const html = `
<div>
<h1>${title}</h1>
<p>${content}</p>
</div>
`;
// Expression evaluation
const price = 19.99;
const total = `Total: $${(price * 1.2).toFixed(2)}`;
// Tagged template literals
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
const value = values[i] || "";
return result + str + `<mark>${value}</mark>`;
}, "");
}
const name = "John";
const age = 30;
const html = highlight`Name: ${name}, Age: ${age}`;
// Output: "Name: <mark>John</mark>, Age: <mark>30</mark>"
const name = "John";
const age = 30;
// Shorthand property names
const user = { name, age };
// Shorthand method names
const calculator = {
add(a, b) {
return a + b;
},
subtract(a, b) {
return a - b;
},
};
// Computed property names
const field = "email";
const user = {
name: "John",
[field]: "john@example.com",
[`get${field.charAt(0).toUpperCase()}${field.slice(1)}`]() {
return this[field];
},
};
// Dynamic property creation
const createUser = (name, ...props) => {
return props.reduce(
(user, [key, value]) => ({
...user,
[key]: value,
}),
{ name },
);
};
const user = createUser("John", ["age", 30], ["email", "john@example.com"]);
Creating and Using Promises:
// Creating a promise
const 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))
.finally(() => console.log("Done"));
// Chaining promises
fetchUser(1)
.then((user) => fetchUserPosts(user.id))
.then((posts) => processPosts(posts))
.then((result) => console.log(result))
.catch((error) => console.error(error));
Promise Combinators:
// Promise.all - Wait for all promises
const promises = [fetchUser(1), fetchUser(2), fetchUser(3)];
Promise.all(promises)
.then((users) => console.log(users))
.catch((error) => console.error("At least one failed:", error));
// Promise.allSettled - Wait for all, regardless of outcome
Promise.allSettled(promises).then((results) => {
results.forEach((result) => {
if (result.status === "fulfilled") {
console.log("Success:", result.value);
} else {
console.log("Error:", result.reason);
}
});
});
// Promise.race - First to complete
Promise.race(promises)
.then((winner) => console.log("First:", winner))
.catch((error) => console.error(error));
// Promise.any - First to succeed
Promise.any(promises)
.then((first) => console.log("First success:", first))
.catch((error) => console.error("All failed:", error));
Basic Usage:
// Async function always returns a Promise
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`);
const user = await response.json();
return user;
}
// Error handling with try/catch
async function getUserData(id) {
try {
const user = await fetchUser(id);
const posts = await fetchUserPosts(user.id);
return { user, posts };
} catch (error) {
console.error("Error fetching data:", error);
throw error;
}
}
// Sequential vs Parallel execution
async function sequential() {
const user1 = await fetchUser(1); // Wait
const user2 = await fetchUser(2); // Then wait
return [user1, user2];
}
async function parallel() {
const [user1, user2] = await Promise.all([fetchUser(1), fetchUser(2)]);
return [user1, user2];
}
Advanced Patterns:
// Async IIFE
(async () => {
const result = await someAsyncOperation();
console.log(result);
})();
// Async iteration
async function processUsers(userIds) {
for (const id of userIds) {
const user = await fetchUser(id);
await processUser(user);
}
}
// Top-level await (ES2022)
const config = await fetch("/config.json").then((r) => r.json());
// Retry logic
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await fetch(url);
} catch (error) {
if (i === retries - 1) throw error;
await new Promise((resolve) => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
// Timeout wrapper
async function withTimeout(promise, ms) {
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error("Timeout")), ms),
);
return Promise.race([promise, timeout]);
}
Map, Filter, Reduce:
const users = [
{ id: 1, name: "John", age: 30, active: true },
{ id: 2, name: "Jane", age: 25, active: false },
{ id: 3, name: "Bob", age: 35, active: true },
];
// Map - Transform array
const names = users.map((user) => user.name);
const upperNames = users.map((user) => user.name.toUpperCase());
// Filter - Select elements
const activeUsers = users.filter((user) => user.active);
const adults = users.filter((user) => user.age >= 18);
// Reduce - Aggregate data
const totalAge = users.reduce((sum, user) => sum + user.age, 0);
const avgAge = totalAge / users.length;
// Group by property
const byActive = users.reduce((groups, user) => {
const key = user.active ? "active" : "inactive";
return {
...groups,
[key]: [...(groups[key] || []), user],
};
}, {});
// Chaining methods
const result = users
.filter((user) => user.active)
.map((user) => user.name)
.sort()
.join(", ");
Advanced Array Methods:
// Find - First matching element
const user = users.find((u) => u.id === 2);
// FindIndex - Index of first match
const index = users.findIndex((u) => u.name === "Jane");
// Some - At least one matches
const hasActive = users.some((u) => u.active);
// Every - All match
const allAdults = users.every((u) => u.age >= 18);
// FlatMap - Map and flatten
const userTags = [
{ name: "John", tags: ["admin", "user"] },
{ name: "Jane", tags: ["user"] },
];
const allTags = userTags.flatMap((u) => u.tags);
// From - Create array from iterable
const str = "hello";
const chars = Array.from(str);
const numbers = Array.from({ length: 5 }, (_, i) => i + 1);
// Of - Create array from arguments
const arr = Array.of(1, 2, 3);
Functions as Arguments:
// Custom forEach
function forEach(array, callback) {
for (let i = 0; i < array.length; i++) {
callback(array[i], i, array);
}
}
// Custom map
function map(array, transform) {
const result = [];
for (const item of array) {
result.push(transform(item));
}
return result;
}
// Custom filter
function filter(array, predicate) {
const result = [];
for (const item of array) {
if (predicate(item)) {
result.push(item);
}
}
return result;
}
Functions Returning Functions:
// Currying
const multiply = (a) => (b) => a * b;
const double = multiply(2);
const triple = multiply(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
// Partial application
function partial(fn, ...args) {
return (...moreArgs) => fn(...args, ...moreArgs);
}
const add = (a, b, c) => a + b + c;
const add5 = partial(add, 5);
console.log(add5(3, 2)); // 10
// Memoization
function memoize(fn) {
const cache = new Map();
return (...args) => {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
return result;
};
}
const fibonacci = memoize((n) => {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
});
// Function composition
const compose =
(...fns) =>
(x) =>
fns.reduceRight((acc, fn) => fn(acc), x);
const pipe =
(...fns) =>
(x) =>
fns.reduce((acc, fn) => fn(acc), x);
// Example usage
const addOne = (x) => x + 1;
const double = (x) => x * 2;
const square = (x) => x * x;
const composed = compose(square, double, addOne);
console.log(composed(3)); // ((3 + 1) * 2)^2 = 64
const piped = pipe(addOne, double, square);
console.log(piped(3)); // ((3 + 1) * 2)^2 = 64
// Practical example
const processUser = pipe(
(user) => ({ ...user, name: user.name.trim() }),
(user) => ({ ...user, email: user.email.toLowerCase() }),
(user) => ({ ...user, age: parseInt(user.age) }),
);
const user = processUser({
name: " John ",
email: "JOHN@EXAMPLE.COM",
age: "30",
});
// Impure function (modifies input)
function addItemImpure(cart, item) {
cart.items.push(item);
cart.total += item.price;
return cart;
}
// Pure function (no side effects)
function addItemPure(cart, item) {
return {
...cart,
items: [...cart.items, item],
total: cart.total + item.price,
};
}
// Immutable array operations
const numbers = [1, 2, 3, 4, 5];
// Add to array
const withSix = [...numbers, 6];
// Remove from array
const withoutThree = numbers.filter((n) => n !== 3);
// Update array element
const doubled = numbers.map((n) => (n === 3 ? n * 2 : n));
// Immutable object operations
const user = { name: "John", age: 30 };
// Update property
const olderUser = { ...user, age: 31 };
// Add property
const withEmail = { ...user, email: "john@example.com" };
// Remove property
const { age, ...withoutAge } = user;
// Deep cloning (simple approach)
const deepClone = (obj) => JSON.parse(JSON.stringify(obj));
// Better deep cloning
const structuredClone = (obj) => globalThis.structuredClone(obj);
// Class syntax
class User {
// Private fields
#password;
// Public fields
id;
name;
// Static field
static count = 0;
constructor(id, name, password) {
this.id = id;
this.name = name;
this.#password = password;
User.count++;
}
// Public method
greet() {
return `Hello, ${this.name}`;
}
// Private method
#hashPassword(password) {
return `hashed_${password}`;
}
// Getter
get displayName() {
return this.name.toUpperCase();
}
// Setter
set password(newPassword) {
this.#password = this.#hashPassword(newPassword);
}
// Static method
static create(id, name, password) {
return new User(id, name, password);
}
}
// Inheritance
class Admin extends User {
constructor(id, name, password, role) {
super(id, name, password);
this.role = role;
}
greet() {
return `${super.greet()}, I'm an admin`;
}
}
// Exporting
// math.js
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export class Calculator {
// ...
}
// Default export
export default function multiply(a, b) {
return a * b;
}
// Importing
// app.js
import multiply, { PI, add, Calculator } from "./math.js";
// Rename imports
import { add as sum } from "./math.js";
// Import all
import * as Math from "./math.js";
// Dynamic imports
const module = await import("./math.js");
const { add } = await import("./math.js");
// Conditional loading
if (condition) {
const module = await import("./feature.js");
module.init();
}
// Custom iterator
const range = {
from: 1,
to: 5,
[Symbol.iterator]() {
return {
current: this.from,
last: this.to,
next() {
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
},
};
},
};
for (const num of range) {
console.log(num); // 1, 2, 3, 4, 5
}
// Generator function
function* rangeGenerator(from, to) {
for (let i = from; i <= to; i++) {
yield i;
}
}
for (const num of rangeGenerator(1, 5)) {
console.log(num);
}
// Infinite generator
function* fibonacci() {
let [prev, curr] = [0, 1];
while (true) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
// Async generator
async function* fetchPages(url) {
let page = 1;
while (true) {
const response = await fetch(`${url}?page=${page}`);
const data = await response.json();
if (data.length === 0) break;
yield data;
page++;
}
}
for await (const page of fetchPages("/api/users")) {
console.log(page);
}
// Optional chaining
const user = { name: "John", address: { city: "NYC" } };
const city = user?.address?.city;
const zipCode = user?.address?.zipCode; // undefined
// Function call
const result = obj.method?.();
// Array access
const first = arr?.[0];
// Nullish coalescing
const value = null ?? "default"; // 'default'
const value = undefined ?? "default"; // 'default'
const value = 0 ?? "default"; // 0 (not 'default')
const value = "" ?? "default"; // '' (not 'default')
// Logical assignment
let a = null;
a ??= "default"; // a = 'default'
let b = 5;
b ??= 10; // b = 5 (unchanged)
let obj = { count: 0 };
obj.count ||= 1; // obj.count = 1
obj.count &&= 2; // obj.count = 2
// Debounce
function debounce(fn, delay) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn(...args), delay);
};
}
const searchDebounced = debounce(search, 300);
// Throttle
function throttle(fn, limit) {
let inThrottle;
return (...args) => {
if (!inThrottle) {
fn(...args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
}
const scrollThrottled = throttle(handleScroll, 100);
// Lazy evaluation
function* lazyMap(iterable, transform) {
for (const item of iterable) {
yield transform(item);
}
}
// Use only what you need
const numbers = [1, 2, 3, 4, 5];
const doubled = lazyMap(numbers, (x) => x * 2);
const first = doubled.next().value; // Only computes first value
'use strict' for better error catchingWeekly Installs
6.5K
Repository
GitHub Stars
32.3K
First Seen
Jan 20, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code5.0K
opencode3.8K
gemini-cli3.7K
codex3.6K
cursor3.4K
github-copilot3.2K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装