JavaScript Cheat Sheet
title: JavaScript date: 2020-12-24 17:12:25 background: bg-[#ebd94e] tags: - js - web - 前端开发 - 编程语言 categories: - Programming intro: | JavaScript 速查表 - 包含 JS 最重要的概念、语法、函数和方法。适合初学者和开发者快速参考的完整指南。 plugins: - copyCode - runCode
入门指南 {.cols-3}
简介
JavaScript 是一种轻量级、解释型的编程语言,是 Web 开发的核心技术之一。
- MDN JavaScript 文档 (developer.mozilla.org)
- JavaScript 正则表达式 (cheatsheets)
- JSON 速查表 (cheatsheets)
- ES6+ 新特性 (cheatsheets)
控制台输出
// 普通输出
console.log('Hello, World!');
// 带格式输出
console.log('用户: %s, 年龄: %d', '张三', 25);
// 警告和错误
console.warn('这是警告信息');
console.error('这是错误信息');
// 表格形式输出
console.table([{ name: '张三', age: 25 }]);
// 分组输出
console.group('用户信息');
console.log('姓名: 张三');
console.log('年龄: 25');
console.groupEnd();
// 计时
console.time('操作耗时');
// ... 一些操作
console.timeEnd('操作耗时');
变量声明
// let - 块级作用域,可重新赋值
let name = '张三';
name = '李四'; // OK
// const - 块级作用域,不可重新赋值
const PI = 3.14159;
// PI = 3.14; // Error!
// var - 函数作用域 (不推荐使用)
var oldStyle = 'legacy';
// 解构赋值
const { firstName, lastName } = user;
const [first, second, ...rest] = array;
// 变量命名:驼峰命名法
let userName = 'admin';
const MAX_SIZE = 100;
数据类型
| 类型 | 说明 | 示例 |
|---|---|---|
string | 字符串 | "hello", 'world' |
number | 数字 | 42, 3.14, NaN |
bigint | 大整数 | 9007199254740991n |
boolean | 布尔值 | true, false |
undefined | 未定义 | undefined |
null | 空值 | null |
symbol | 符号 | Symbol('id') |
object | 对象 | {}, [], function |
// 类型检查
typeof 'hello'; // "string"
typeof 42; // "number"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof null; // "object" (历史遗留bug)
typeof {}; // "object"
typeof []; // "object"
Array.isArray([]); // true
字符串
// 字符串创建
const single = '单引号';
const double = '双引号';
const template = `模板字符串 ${variable}`;
// 多行字符串
const multiLine = `
这是一个
多行字符串
`;
// 字符串长度
'Hello'.length; // 5
// 常用方法
str.toUpperCase(); // 转大写
str.toLowerCase(); // 转小写
str.trim(); // 去除首尾空格
str.split(','); // 分割为数组
str.includes('hello'); // 是否包含
str.startsWith('He'); // 是否以...开头
str.endsWith('lo'); // 是否以...结尾
str.indexOf('l'); // 查找索引
str.slice(0, 5); // 截取子串
str.replace('a', 'b'); // 替换
str.padStart(10, '0'); // 填充到指定长度
模板字符串
const name = '张三';
const age = 25;
// 变量插值
const greeting = `你好,${name}!`;
// 表达式
const message = `明年 ${age + 1} 岁`;
// 多行
const html = `
<div class="user">
<h2>${name}</h2>
<p>年龄: ${age}</p>
</div>
`;
// 标签模板
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
return `${result}${str}<mark>${values[i] || ''}</mark>`;
}, '');
}
const result = highlight`姓名是 ${name}`;
运算符
// 算术运算符
5 + 3; // 8 加法
5 - 3; // 2 减法
5 * 3; // 15 乘法
5 / 3; // 1.666... 除法
5 % 3; // 2 取余
5 ** 3; // 125 幂运算
// 比较运算符
5 == '5'; // true (类型转换后比较)
5 === '5'; // false (严格相等,推荐使用)
5 !== '5'; // true (严格不等)
// 逻辑运算符
true && false; // false (与)
true || false; // true (或)
!true; // false (非)
// 空值合并运算符 (??)
null ?? 'default'; // 'default'
undefined ?? 'default'; // 'default'
0 ?? 'default'; // 0
'' ?? 'default'; // ''
// 可选链运算符 (?.)
user?.address?.city; // 安全访问嵌套属性
user?.getName?.(); // 安全调用方法
类型转换
// 转字符串
String(123)(
// "123"
123
).toString(); // "123"
123 + ''; // "123"
// 转数字
Number('123'); // 123
parseInt('123'); // 123
parseFloat('3.14') + // 3.14
'123'; // 123
// 转布尔
Boolean(1); // true
Boolean(0); // false
Boolean(''); // false
Boolean('hello'); // true
!!value; // 快捷转换
// 假值 (Falsy values)
// false, 0, -0, 0n, '', null, undefined, NaN
条件语句 {.cols-2}
if-else 语句
const score = 85;
if (score >= 90) {
console.log('优秀');
} else if (score >= 80) {
console.log('良好');
} else if (score >= 60) {
console.log('及格');
} else {
console.log('不及格');
}
// 简写 (单行)
if (condition) doSomething();
// 短路求值
isAdmin && showAdminPanel();
isError || showDefaultMessage();
三元运算符
// 基本用法
const result = condition ? '真' : '假';
// 嵌套 (不推荐过度嵌套)
const grade = score >= 90 ? 'A' : score >= 80 ? 'B' : score >= 70 ? 'C' : 'D';
// 配合赋值
const message = user ? `欢迎, ${user.name}!` : '请登录';
// 条件执行
isLoggedIn ? showDashboard() : redirectToLogin();
switch 语句
const fruit = 'apple';
switch (fruit) {
case 'apple':
console.log('苹果');
break;
case 'banana':
case 'orange': // 多个条件
console.log('香蕉或橙子');
break;
default:
console.log('未知水果');
}
// 表达式 switch
const day = new Date().getDay();
switch (true) {
case day === 0:
case day === 6:
console.log('周末');
break;
default:
console.log('工作日');
}
逻辑运算符技巧
// && 短路求值 - 条件执行
user && user.name && console.log(user.name);
// || 短路求值 - 默认值
const name = userName || '匿名用户';
// ?? 空值合并 - 仅当 null/undefined 时取默认值
const count = userCount ?? 0; // 0 和 '' 不会被替换
// 可选链 + 空值合并
const city = user?.address?.city ?? '未知城市';
// 逻辑赋值运算符 (ES2021)
x ||= y; // x = x || y
x &&= y; // x = x && y
x ??= y; // x = x ?? y
函数 {.cols-2}
函数声明
// 函数声明 (会被提升)
function greet(name) {
return `Hello, ${name}!`;
}
// 函数表达式
const greet = function (name) {
return `Hello, ${name}!`;
};
// 箭头函数 (ES6)
const greet = name => {
return `Hello, ${name}!`;
};
// 箭头函数简写
const greet = name => `Hello, ${name}!`;
const add = (a, b) => a + b;
const getUser = () => ({ name: '张三' });
// 立即执行函数 (IIFE)
(function () {
console.log('立即执行');
})();
参数处理
// 默认参数
function greet(name = '访客') {
return `Hello, ${name}!`;
}
// 剩余参数
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10
// 解构参数
function createUser({ name, age, email = '' }) {
return { name, age, email };
}
createUser({ name: '张三', age: 25 });
// 参数展开
const nums = [1, 2, 3];
Math.max(...nums); // 3
// arguments 对象 (不推荐)
function oldStyle() {
console.log(arguments); // 类数组对象
}
箭头函数 {.row-span-2}
// 基本语法
const add = (a, b) => a + b;
// 单参数可省略括号
const square = x => x * x;
// 无参数
const sayHello = () => console.log('Hello!');
// 多行函数体
const calculate = (a, b) => {
const sum = a + b;
const product = a * b;
return { sum, product };
};
// 返回对象字面量 (需要括号)
const createUser = name => ({ name, createdAt: Date.now() });
// 箭头函数没有自己的 this
const obj = {
name: '张三',
// 不要用箭头函数作为对象方法
greet: function () {
console.log(`Hello, ${this.name}`);
},
// 在回调中使用箭头函数
delayedGreet: function () {
setTimeout(() => {
console.log(`Hello, ${this.name}`); // this 正确
}, 1000);
}
};
// 箭头函数不能作为构造函数
// const Person = (name) => { this.name = name; };
// new Person('张三'); // Error!
高阶函数
// 函数作为参数
function applyOperation(a, b, operation) {
return operation(a, b);
}
applyOperation(5, 3, (x, y) => x + y); // 8
// 函数作为返回值
function multiplier(factor) {
return number => number * factor;
}
const double = multiplier(2);
double(5); // 10
// 柯里化
const curry = fn => {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return (...args2) => curried(...args, ...args2);
};
};
const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
curriedAdd(1)(2)(3); // 6
curriedAdd(1, 2)(3); // 6
闭包
// 基本闭包
function createCounter() {
let count = 0;
return {
increment: () => ++count,
decrement: () => --count,
getCount: () => count
};
}
const counter = createCounter();
counter.increment(); // 1
counter.increment(); // 2
counter.getCount(); // 2
// 私有变量模式
function createPerson(name) {
let _age = 0; // 私有变量
return {
getName: () => name,
getAge: () => _age,
setAge: age => {
if (age > 0) _age = age;
}
};
}
// 模块模式
const Calculator = (function () {
let result = 0;
return {
add: n => (result += n),
subtract: n => (result -= n),
getResult: () => result,
reset: () => (result = 0)
};
})();
数组 {.cols-2}
数组基础
// 创建数组
const arr1 = [1, 2, 3];
const arr2 = new Array(3); // [empty × 3]
const arr3 = Array.of(1, 2, 3); // [1, 2, 3]
const arr4 = Array.from('abc'); // ['a', 'b', 'c']
const arr5 = Array(5).fill(0); // [0, 0, 0, 0, 0]
// 访问元素
arr[0]; // 第一个元素
arr[arr.length - 1]; // 最后一个元素
arr.at(-1); // 最后一个元素 (ES2022)
// 解构
const [first, second, ...rest] = arr;
const [a, , c] = [1, 2, 3]; // 跳过元素
数组方法 - 修改
const arr = [1, 2, 3];
// 添加元素
arr.push(4); // 末尾添加,返回新长度
arr.unshift(0); // 开头添加,返回新长度
// 删除元素
arr.pop(); // 删除并返回最后一个
arr.shift(); // 删除并返回第一个
// 修改元素
arr.splice(1, 1, 'new'); // 从索引1删除1个,插入'new'
arr.splice(1, 0, 'a', 'b'); // 插入不删除
// 排序
arr.sort(); // 字符串排序
arr.sort((a, b) => a - b); // 数字升序
arr.sort((a, b) => b - a); // 数字降序
arr.reverse(); // 反转
// 填充
arr.fill(0); // 全部填充为0
arr.fill(0, 1, 3); // 从索引1到3填充
// 复制
arr.copyWithin(0, 2); // 将索引2开始的元素复制到0
数组方法 - 不修改
const arr = [1, 2, 3, 4, 5];
// 查找
arr.indexOf(3) // 2 (找不到返回-1)
arr.lastIndexOf(3) // 从后查找
arr.includes(3) // true
arr.find(x => x > 3) // 4 (第一个满足条件的元素)
arr.findIndex(x => x > 3) // 3 (第一个满足条件的索引)
arr.findLast(x => x > 3) // 5 (ES2023)
// 切片
arr.slice(1, 3) // [2, 3] (不包含索引3)
arr.slice(-2) // [4, 5] (最后2个)
// 合并
arr.concat([6, 7]) // [1, 2, 3, 4, 5, 6, 7]
[...arr, 6, 7] // 展开运算符
// 转换
arr.join('-') // "1-2-3-4-5"
arr.toString() // "1,2,3,4,5"
// 检查
arr.every(x => x > 0) // true (全部满足)
arr.some(x => x > 4) // true (至少一个满足)
数组迭代方法 {.row-span-2}
const numbers = [1, 2, 3, 4, 5];
// forEach - 遍历
numbers.forEach((value, index, array) => {
console.log(`${index}: ${value}`);
});
// map - 映射
const doubled = numbers.map(x => x * 2);
// [2, 4, 6, 8, 10]
// filter - 过滤
const evens = numbers.filter(x => x % 2 === 0);
// [2, 4]
// reduce - 归约
const sum = numbers.reduce((acc, cur) => acc + cur, 0);
// 15
// reduceRight - 从右到左归约
const reversed = numbers.reduceRight((acc, cur) => acc + cur, '');
// flatMap - 映射并扁平化
const sentences = ['hello world', 'foo bar'];
sentences.flatMap(s => s.split(' '));
// ['hello', 'world', 'foo', 'bar']
// 链式调用
const result = numbers
.filter(x => x > 2)
.map(x => x * 2)
.reduce((a, b) => a + b, 0);
// 24 = (3*2 + 4*2 + 5*2)
// 常见用法
// 求最大值
Math.max(...numbers);
numbers.reduce((a, b) => Math.max(a, b));
// 数组去重
[...new Set(numbers)];
numbers.filter((v, i, a) => a.indexOf(v) === i);
// 数组分组 (ES2024)
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 }
];
Object.groupBy(users, u => (u.age >= 30 ? 'senior' : 'junior'));
数组扁平化
const nested = [1, [2, 3], [4, [5, 6]]];
// flat() - 扁平化
nested.flat(); // [1, 2, 3, 4, [5, 6]]
nested.flat(2); // [1, 2, 3, 4, 5, 6]
nested.flat(Infinity); // 完全扁平化
// flatMap() - map + flat(1)
const pairs = [
[1, 2],
[3, 4],
[5, 6]
];
pairs.flatMap(([a, b]) => [a, b, a + b]);
// [1, 2, 3, 3, 4, 7, 5, 6, 11]
// 递归扁平化
function flatten(arr) {
return arr.reduce((flat, item) => {
return flat.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}
对象 {.cols-2}
对象基础
// 创建对象
const obj = {
name: '张三',
age: 25,
'multi-word': 'value', // 特殊键名
sayHello() {
// 方法简写
return `Hello, ${this.name}!`;
}
};
// 访问属性
obj.name; // 点语法
obj['name']; // 方括号语法
obj['multi-word']; // 特殊键名必须用方括号
// 动态属性名
const key = 'name';
obj[key]; // '张三'
// 属性简写
const name = '张三';
const age = 25;
const user = { name, age }; // { name: '张三', age: 25 }
// 计算属性名
const propName = 'score';
const student = {
[propName]: 100,
[`get${propName}`]() {
return this[propName];
}
};
对象操作
const obj = { a: 1, b: 2 };
// 添加/修改属性
obj.c = 3;
obj['d'] = 4;
// 删除属性
delete obj.a;
// 检查属性
'a' in obj; // true
obj.hasOwnProperty('a'); // true
// 遍历
Object.keys(obj); // ['a', 'b']
Object.values(obj); // [1, 2]
Object.entries(obj); // [['a', 1], ['b', 2]]
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key, obj[key]);
}
}
// 合并对象
const merged = { ...obj, c: 3 };
const merged2 = Object.assign({}, obj, { c: 3 });
// 浅拷贝
const copy = { ...obj };
const copy2 = Object.assign({}, obj);
// 深拷贝
const deep = JSON.parse(JSON.stringify(obj));
const deep2 = structuredClone(obj); // 现代方法
解构赋值
const user = {
name: '张三',
age: 25,
address: {
city: '北京',
country: '中国'
}
};
// 基本解构
const { name, age } = user;
// 重命名
const { name: userName, age: userAge } = user;
// 默认值
const { email = 'unknown' } = user;
// 嵌套解构
const {
address: { city }
} = user;
// 剩余属性
const { name: n, ...rest } = user;
// 函数参数解构
function greet({ name, age = 0 }) {
return `${name}, ${age}岁`;
}
// 数组解构
const [first, second, ...others] = [1, 2, 3, 4, 5];
const [a, , c] = [1, 2, 3]; // 跳过元素
// 交换变量
let x = 1,
y = 2;
[x, y] = [y, x];
对象方法
const obj = { a: 1, b: 2, c: 3 };
// 获取键/值/条目
Object.keys(obj); // ['a', 'b', 'c']
Object.values(obj); // [1, 2, 3]
Object.entries(obj); // [['a', 1], ['b', 2], ['c', 3]]
// 从条目创建对象
Object.fromEntries([
['a', 1],
['b', 2]
]); // { a: 1, b: 2 }
// 冻结/密封
Object.freeze(obj); // 不可修改、添加、删除
Object.seal(obj); // 不可添加、删除,可修改
Object.isFrozen(obj); // 检查是否冻结
Object.isSealed(obj); // 检查是否密封
// 属性描述符
Object.defineProperty(obj, 'x', {
value: 10,
writable: false, // 不可写
enumerable: true, // 可枚举
configurable: false // 不可配置
});
// 获取属性描述符
Object.getOwnPropertyDescriptor(obj, 'a');
// 原型操作
Object.getPrototypeOf(obj);
Object.setPrototypeOf(obj, proto);
类 (ES6+) {.cols-2}
类定义
class Person {
// 类字段 (ES2022)
name;
#privateField = 'private'; // 私有字段
// 静态字段
static species = 'Human';
// 构造函数
constructor(name, age) {
this.name = name;
this.age = age;
}
// 实例方法
greet() {
return `Hello, I'm ${this.name}`;
}
// Getter
get info() {
return `${this.name}, ${this.age}岁`;
}
// Setter
set info(value) {
[this.name, this.age] = value.split(',');
}
// 私有方法 (ES2022)
#privateMethod() {
return this.#privateField;
}
// 静态方法
static create(name) {
return new Person(name, 0);
}
}
const person = new Person('张三', 25);
person.greet(); // "Hello, I'm 张三"
person.info; // "张三, 25岁"
Person.species; // "Human"
Person.create('李四'); // Person { name: '李四', age: 0 }
继承
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 必须先调用 super()
this.breed = breed;
}
// 方法重写
speak() {
console.log(`${this.name} barks.`);
}
// 调用父类方法
speakLoud() {
super.speak();
console.log('WOOF!');
}
}
const dog = new Dog('Buddy', 'Labrador');
dog.speak(); // "Buddy barks."
dog.speakLoud(); // "Buddy makes a sound." "WOOF!"
// 检查继承关系
dog instanceof Dog; // true
dog instanceof Animal; // true
Getter 和 Setter
class Circle {
#radius; // 私有属性
constructor(radius) {
this.#radius = radius;
}
// Getter - 获取计算属性
get radius() {
return this.#radius;
}
// Setter - 带验证的设置
set radius(value) {
if (value < 0) {
throw new Error('半径不能为负数');
}
this.#radius = value;
}
// 只读属性
get area() {
return Math.PI * this.#radius ** 2;
}
get circumference() {
return 2 * Math.PI * this.#radius;
}
}
const circle = new Circle(5);
console.log(circle.radius); // 5
console.log(circle.area); // 78.54...
circle.radius = 10; // 修改半径
// circle.radius = -1; // Error!
静态成员
class MathUtils {
// 静态属性
static PI = 3.14159;
// 静态方法
static add(a, b) {
return a + b;
}
static multiply(a, b) {
return a * b;
}
// 静态初始化块 (ES2022)
static {
console.log('MathUtils 类被加载');
}
}
// 直接通过类名调用
MathUtils.PI; // 3.14159
MathUtils.add(2, 3); // 5
// 静态工厂模式
class User {
constructor(name, role) {
this.name = name;
this.role = role;
}
static createAdmin(name) {
return new User(name, 'admin');
}
static createGuest() {
return new User('Guest', 'guest');
}
}
const admin = User.createAdmin('张三');
const guest = User.createGuest();
Promise 和异步 {.cols-2}
Promise 基础
// 创建 Promise
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true;
if (success) {
resolve('操作成功');
} else {
reject(new Error('操作失败'));
}
}, 1000);
});
// 使用 Promise
promise
.then(result => {
console.log(result); // '操作成功'
return '下一步';
})
.then(next => {
console.log(next); // '下一步'
})
.catch(error => {
console.error(error);
})
.finally(() => {
console.log('无论成功失败都执行');
});
// 快捷创建
Promise.resolve('立即成功');
Promise.reject(new Error('立即失败'));
Promise 方法
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.reject('error');
// Promise.all - 全部成功
Promise.all([p1, p2]).then(results => console.log(results)); // [1, 2]
// Promise.allSettled - 等待全部完成
Promise.allSettled([p1, p2, p3]).then(results => {
// [
// { status: 'fulfilled', value: 1 },
// { status: 'fulfilled', value: 2 },
// { status: 'rejected', reason: 'error' }
// ]
});
// Promise.race - 第一个完成
Promise.race([p1, p2]).then(result => console.log(result)); // 1
// Promise.any - 第一个成功 (ES2021)
Promise.any([p3, p1, p2]).then(result => console.log(result)); // 1
async/await
// async 函数自动返回 Promise
async function fetchUser(id) {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error('请求失败');
}
const user = await response.json();
return user;
} catch (error) {
console.error('获取用户失败:', error);
throw error;
}
}
// 使用
fetchUser(1)
.then(user => console.log(user))
.catch(error => console.error(error));
// 或者在另一个 async 函数中
async function main() {
const user = await fetchUser(1);
console.log(user);
}
// 并行执行
async function fetchAll() {
const [users, posts] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
]);
return { users, posts };
}
// 顶层 await (ES2022, 模块中)
const data = await fetch('/api/data').then(r => r.json());
错误处理
// try-catch 捕获 await 错误
async function fetchData() {
try {
const response = await fetch('/api/data');
const data = await response.json();
return data;
} catch (error) {
console.error('请求错误:', error);
return null;
} finally {
console.log('请求完成');
}
}
// 错误处理工具函数
async function tryCatch(promise) {
try {
const data = await promise;
return [null, data];
} catch (error) {
return [error, null];
}
}
// 使用
const [error, data] = await tryCatch(fetchData());
if (error) {
console.error(error);
} else {
console.log(data);
}
// Promise 错误处理
fetchData()
.then(data => console.log(data))
.catch(error => console.error(error));
模块 {.cols-2}
ES 模块 (ESM)
// 导出 - 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;
}
// 导出列表
const subtract = (a, b) => a - b;
const divide = (a, b) => a / b;
export { subtract, divide };
// 重命名导出
export { subtract as minus };
导入
// 导入命名导出
import { PI, add, Calculator } from './math.js';
// 导入默认导出
import multiply from './math.js';
// 混合导入
import multiply, { PI, add } from './math.js';
// 重命名导入
import { add as sum } from './math.js';
// 导入全部
import * as math from './math.js';
math.PI;
math.add(1, 2);
// 动态导入
const module = await import('./math.js');
// 或
import('./math.js').then(module => {
console.log(module.PI);
});
// 重新导出
export { add, subtract } from './math.js';
export * from './math.js';
export { default } from './math.js';
CommonJS (Node.js)
// 导出 - math.js
module.exports = {
PI: 3.14159,
add: (a, b) => a + b,
subtract: (a, b) => a - b
};
// 或者
exports.PI = 3.14159;
exports.add = (a, b) => a + b;
// 默认导出
module.exports = function multiply(a, b) {
return a * b;
};
// 导入
const math = require('./math');
const { PI, add } = require('./math');
// 条件导入
let module;
if (condition) {
module = require('./moduleA');
} else {
module = require('./moduleB');
}
实用技巧 {.cols-2}
常用操作
// 数组去重
const unique = [...new Set(array)];
// 数组最大/最小值
const max = Math.max(...numbers);
const min = Math.min(...numbers);
// 生成范围数组
const range = Array.from({ length: 10 }, (_, i) => i);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// 打乱数组
const shuffle = arr => arr.sort(() => Math.random() - 0.5);
// 深拷贝
const deepCopy = obj => structuredClone(obj);
// 或 JSON.parse(JSON.stringify(obj))
// 防抖
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// 节流
function throttle(fn, limit) {
let inThrottle;
return function (...args) {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
}
字符串处理
// 首字母大写
const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1);
// 驼峰转换
const toCamelCase = str => str.replace(/[-_](.)/g, (_, c) => c.toUpperCase());
// 截断字符串
const truncate = (str, len) => (str.length > len ? str.slice(0, len) + '...' : str);
// 移除 HTML 标签
const stripHtml = str => str.replace(/<[^>]*>/g, '');
// 随机字符串
const randomString = len =>
Math.random()
.toString(36)
.substring(2, 2 + len);
// URL 参数解析
const getUrlParams = url => Object.fromEntries(new URL(url).searchParams);
// 模板替换
const template = (str, data) => str.replace(/\{\{(\w+)\}\}/g, (_, key) => data[key] || '');
template('Hello, {{name}}!', { name: '张三' });
// "Hello, 张三!"
对象操作
// 安全访问嵌套属性
const get = (obj, path, def) => {
const keys = path.split('.');
return keys.reduce((o, k) => o?.[k], obj) ?? def;
};
get(user, 'address.city', '未知');
// 对象过滤
const pick = (obj, keys) => Object.fromEntries(keys.map(k => [k, obj[k]]));
pick({ a: 1, b: 2, c: 3 }, ['a', 'c']); // { a: 1, c: 3 }
const omit = (obj, keys) =>
Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));
omit({ a: 1, b: 2, c: 3 }, ['b']); // { a: 1, c: 3 }
// 对象判空
const isEmpty = obj => obj === null || obj === undefined || Object.keys(obj).length === 0;
// 深度合并
const deepMerge = (target, source) => {
for (const key of Object.keys(source)) {
if (source[key] instanceof Object && key in target) {
Object.assign(source[key], deepMerge(target[key], source[key]));
}
}
return { ...target, ...source };
};
日期处理
// 格式化日期
const formatDate = (date, fmt = 'YYYY-MM-DD') => {
const d = new Date(date);
const map = {
YYYY: d.getFullYear(),
MM: String(d.getMonth() + 1).padStart(2, '0'),
DD: String(d.getDate()).padStart(2, '0'),
HH: String(d.getHours()).padStart(2, '0'),
mm: String(d.getMinutes()).padStart(2, '0'),
ss: String(d.getSeconds()).padStart(2, '0')
};
return fmt.replace(/YYYY|MM|DD|HH|mm|ss/g, m => map[m]);
};
formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss');
// "2024-01-15 14:30:00"
// 相对时间
const timeAgo = date => {
const seconds = Math.floor((Date.now() - new Date(date)) / 1000);
const intervals = [
{ label: '年', seconds: 31536000 },
{ label: '月', seconds: 2592000 },
{ label: '天', seconds: 86400 },
{ label: '小时', seconds: 3600 },
{ label: '分钟', seconds: 60 }
];
for (const { label, seconds: s } of intervals) {
const count = Math.floor(seconds / s);
if (count >= 1) return `${count}${label}前`;
}
return '刚刚';
};
// 判断是否为同一天
const isSameDay = (d1, d2) => d1.toDateString() === d2.toDateString();
性能优化
// 延迟执行
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
await delay(1000);
// 缓存/记忆化
const 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;
};
};
// 分批处理
async function processBatch(items, batchSize, processor) {
for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
await Promise.all(batch.map(processor));
}
}
// 并发控制
async function withConcurrency(tasks, limit) {
const results = [];
const executing = new Set();
for (const task of tasks) {
const promise = task().then(result => {
executing.delete(promise);
return result;
});
results.push(promise);
executing.add(promise);
if (executing.size >= limit) {
await Promise.race(executing);
}
}
return Promise.all(results);
}