JavaScript Cheat Sheet - 快速参考指南,收录常用语法、命令与实践。
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
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();
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
// 函数声明 (会被提升)
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); // 类数组对象
}
// 基本语法
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)
};
})();
// 创建数组
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 (至少一个满足)
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);
}, []);
}
// 创建对象
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);
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
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
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('立即失败'));
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 函数自动返回 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));
// 导出 - 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';
// 导出 - 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');
}
// 数组去重
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);
}
地址
Level 10b, 144 Edward Street, Brisbane CBD(Headquarter)Level 2, 171 La Trobe St, Melbourne VIC 3000四川省成都市武侯区桂溪街道天府大道中段500号D5东方希望天祥广场B座45A13号Business Hub, 155 Waymouth St, Adelaide SA 5000Disclaimer
JR Academy acknowledges Traditional Owners of Country throughout Australia and recognises the continuing connection to lands, waters and communities. We pay our respect to Aboriginal and Torres Strait Islander cultures; and to Elders past and present. Aboriginal and Torres Strait Islander peoples should be aware that this website may contain images or names of people who have since passed away.
匠人学院网站上的所有内容,包括课程材料、徽标和匠人学院网站上提供的信息,均受澳大利亚政府知识产权法的保护。严禁未经授权使用、销售、分发、复制或修改。违规行为可能会导致法律诉讼。通过访问我们的网站,您同意尊重我们的知识产权。 JR Academy Pty Ltd 保留所有权利,包括专利、商标和版权。任何侵权行为都将受到法律追究。查看用户协议
© 2017-2025 JR Academy Pty Ltd. All rights reserved.
ABN 26621887572