logo

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 开发的核心技术之一。

控制台输出

// 普通输出
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);
}
💻 编程语言

JavaScript

JavaScript Cheat Sheet - 快速参考指南,收录常用语法、命令与实践。

📂 分类 · 编程语言🧭 Markdown 速查🏷️ 2 个标签
#js#web
向下滚动查看内容
返回全部 Cheat Sheets

入门指南

简介

JavaScript 是一种轻量级、解释型的编程语言,是 Web 开发的核心技术之一。

控制台输出
JAVASCRIPT
滚动查看更多
// 普通输出
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('操作耗时');
变量声明
JAVASCRIPT
滚动查看更多
// 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
JAVASCRIPT
滚动查看更多
// 类型检查
typeof 'hello'; // "string"
typeof 42; // "number"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof null; // "object" (历史遗留bug)
typeof {}; // "object"
typeof []; // "object"
Array.isArray([]); // true
字符串
JAVASCRIPT
滚动查看更多
// 字符串创建
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'); // 填充到指定长度
模板字符串
JAVASCRIPT
滚动查看更多
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}`;
运算符
JAVASCRIPT
滚动查看更多
// 算术运算符
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?.(); // 安全调用方法
类型转换
JAVASCRIPT
滚动查看更多
// 转字符串
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

条件语句

if-else 语句
JAVASCRIPT
滚动查看更多
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();
三元运算符
JAVASCRIPT
滚动查看更多
// 基本用法
const result = condition ? '真' : '假';

// 嵌套 (不推荐过度嵌套)
const grade = score >= 90 ? 'A' : score >= 80 ? 'B' : score >= 70 ? 'C' : 'D';

// 配合赋值
const message = user ? `欢迎, ${user.name}!` : '请登录';

// 条件执行
isLoggedIn ? showDashboard() : redirectToLogin();
switch 语句
JAVASCRIPT
滚动查看更多
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('工作日');
}
逻辑运算符技巧
JAVASCRIPT
滚动查看更多
// && 短路求值 - 条件执行
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

函数

函数声明
JAVASCRIPT
滚动查看更多
// 函数声明 (会被提升)
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('立即执行');
})();
参数处理
JAVASCRIPT
滚动查看更多
// 默认参数
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); // 类数组对象
}
箭头函数
JAVASCRIPT
滚动查看更多
// 基本语法
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!
高阶函数
JAVASCRIPT
滚动查看更多
// 函数作为参数
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
闭包
JAVASCRIPT
滚动查看更多
// 基本闭包
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)
	};
})();

数组

数组基础
JAVASCRIPT
滚动查看更多
// 创建数组
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]; // 跳过元素
数组方法 - 修改
JAVASCRIPT
滚动查看更多
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
数组方法 - 不修改
JAVASCRIPT
滚动查看更多
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 (至少一个满足)
数组迭代方法
JAVASCRIPT
滚动查看更多
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'));
数组扁平化
JAVASCRIPT
滚动查看更多
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);
	}, []);
}

对象

对象基础
JAVASCRIPT
滚动查看更多
// 创建对象
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];
	}
};
对象操作
JAVASCRIPT
滚动查看更多
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); // 现代方法
解构赋值
JAVASCRIPT
滚动查看更多
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];
对象方法
JAVASCRIPT
滚动查看更多
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+)

类定义
JAVASCRIPT
滚动查看更多
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 }
继承
JAVASCRIPT
滚动查看更多
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
JAVASCRIPT
滚动查看更多
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!
静态成员
JAVASCRIPT
滚动查看更多
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 和异步

Promise 基础
JAVASCRIPT
滚动查看更多
// 创建 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 方法
JAVASCRIPT
滚动查看更多
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
JAVASCRIPT
滚动查看更多
// 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());
错误处理
JAVASCRIPT
滚动查看更多
// 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));

模块

ES 模块 (ESM)
JAVASCRIPT
滚动查看更多
// 导出 - 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 };
导入
JAVASCRIPT
滚动查看更多
// 导入命名导出
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)
JAVASCRIPT
滚动查看更多
// 导出 - 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');
}

实用技巧

常用操作
JAVASCRIPT
滚动查看更多
// 数组去重
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);
		}
	};
}
字符串处理
JAVASCRIPT
滚动查看更多
// 首字母大写
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, 张三!"
对象操作
JAVASCRIPT
滚动查看更多
// 安全访问嵌套属性
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 };
};
日期处理
JAVASCRIPT
滚动查看更多
// 格式化日期
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();
性能优化
JAVASCRIPT
滚动查看更多
// 延迟执行
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);
}

相关 Cheat Sheets