汇总 JavaScript 内置对象常用方法详解

汇总 JavaScript 内置对象常用方法详解

JavaScript 提供了许多强大的内置对象,它们带有各种实用的方法,能够帮助我们更高效地编写代码。本文将介绍最常用的内置对象方法,并通过实例展示它们的使用场景。

目录

  • Array 数组
  • String 字符串
  • Object 对象
  • Date 日期
  • Math 数学
  • Promise 异步处理

Array 数组

1. map() - 映射数组

使用场景:当你需要对数组的每个元素进行相同的操作,并返回一个新数组时。

示例代码

// 将数组中的每个数字翻倍
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((num) => num * 2);
console.log(doubled); // 输出: [2, 4, 6, 8, 10]// 从对象数组中提取特定属性
const users = [{ name: "张三", age: 25 },{ name: "李四", age: 30 },{ name: "王五", age: 22 },
];
const names = users.map((user) => user.name);
console.log(names); // 输出: ['张三', '李四', '王五']

图解

image-20250427165111353

注意事项

  • map() 不会修改原数组,而是返回一个新数组
  • 对空数组调用 map() 会返回空数组
  • 如果不需要返回值,考虑使用 forEach() 方法

2. filter() - 过滤数组

使用场景:当你需要从数组中筛选出符合条件的元素时。

示例代码

// 筛选出大于10的数字
const numbers = [5, 12, 8, 20, 3];
const largeNumbers = numbers.filter((num) => num > 10);
console.log(largeNumbers); // 输出: [12, 20]// 筛选出年龄大于25的用户
const users = [{ name: "张三", age: 25 },{ name: "李四", age: 30 },{ name: "王五", age: 22 },
];
const adults = users.filter((user) => user.age > 25);
console.log(adults); // 输出: [{ name: '李四', age: 30 }]

图解

image-20250427165128630

注意事项

  • filter() 不会修改原数组
  • 如果没有元素满足条件,返回空数组
  • filter() 会跳过数组中的空位

3. reduce() - 累加器

使用场景:当你需要将数组中的所有元素归纳为单个值时。

示例代码

// 计算数组元素总和
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue,0
);
console.log(sum); // 输出: 15// 统计数组中各元素出现次数
const fruits = ["苹果", "香蕉", "苹果", "橙子", "香蕉", "苹果"];
const countMap = fruits.reduce((acc, fruit) => {acc[fruit] = (acc[fruit] || 0) + 1;return acc;
}, {});
console.log(countMap); // 输出: { '苹果': 3, '香蕉': 2, '橙子': 1 }

注意事项

  • reduce() 需要一个回调函数和一个初始值(可选)
  • 如果没有提供初始值,会使用数组的第一个元素作为初始值
  • 在空数组上调用 reduce() 没有初始值会报错

4. forEach() - 遍历数组

使用场景:当你需要对数组中的每个元素执行操作,但不需要返回新数组时。

示例代码

// 打印数组中的每个元素
const fruits = ["苹果", "香蕉", "橙子"];
fruits.forEach((fruit, index) => {console.log(`${index}: ${fruit}`);
});
// 输出:
// 0: 苹果
// 1: 香蕉
// 2: 橙子// 对象数组操作
const users = [{ name: "张三", age: 25 },{ name: "李四", age: 30 },
];
let totalAge = 0;
users.forEach((user) => {totalAge += user.age;
});
console.log(`平均年龄: ${totalAge / users.length}`); // 输出: 平均年龄: 27.5

注意事项

  • forEach() 不会返回值,总是返回 undefined
  • 无法使用 break 或 continue 中断循环,如需中断应使用普通 for 循环
  • 如果需要构建新数组,使用 map()、filter() 等方法更适合

5. find() 和 findIndex() - 查找元素

使用场景:当你需要在数组中查找符合条件的元素或其索引时。

示例代码

// 查找第一个偶数
const numbers = [1, 3, 5, 8, 9, 10];
const firstEven = numbers.find((num) => num % 2 === 0);
console.log(firstEven); // 输出: 8// 查找符合条件元素的索引
const firstEvenIndex = numbers.findIndex((num) => num % 2 === 0);
console.log(firstEvenIndex); // 输出: 3// 在对象数组中查找
const users = [{ id: 1, name: "张三" },{ id: 2, name: "李四" },{ id: 3, name: "王五" },
];
const user = users.find((user) => user.id === 2);
console.log(user); // 输出: { id: 2, name: "李四" }

注意事项

  • find() 返回第一个满足条件的元素,findIndex() 返回其索引
  • 如果没有找到匹配项,find() 返回 undefined,findIndex() 返回 -1
  • ES6 新增方法,对于旧浏览器可能需要 polyfill

6. some() 和 every() - 条件检查

使用场景:当你需要检查数组是否满足某些条件时。

示例代码

const numbers = [1, 2, 3, 4, 5];// some() 检查是否至少有一个元素满足条件
const hasEven = numbers.some((num) => num % 2 === 0);
console.log(hasEven); // 输出: true// every() 检查是否所有元素都满足条件
const allPositive = numbers.every((num) => num > 0);
console.log(allPositive); // 输出: trueconst allEven = numbers.every((num) => num % 2 === 0);
console.log(allEven); // 输出: false// 实际应用:表单验证
const formValues = [{ field: "username", value: "user123" },{ field: "email", value: "test@example.com" },{ field: "password", value: "" },
];
const isFormValid = formValues.every((field) => field.value.length > 0);
console.log(isFormValid); // 输出: false

注意事项

  • some() 在找到第一个满足条件的元素时就会返回 true 并停止遍历
  • every() 在找到第一个不满足条件的元素时就会返回 false 并停止遍历
  • 对空数组调用 every() 总是返回 true,对空数组调用 some() 总是返回 false

7. sort() - 排序数组

使用场景:当你需要对数组元素进行排序时。

示例代码

// 字符串数组排序(默认按字母顺序)
const fruits = ["香蕉", "苹果", "橙子", "葡萄"];
fruits.sort();
console.log(fruits); // 输出: ["橙子", "苹果", "葡萄", "香蕉"]// 数字数组排序(需要比较函数)
const numbers = [40, 100, 1, 5, 25, 10];
// 升序排序
numbers.sort((a, b) => a - b);
console.log(numbers); // 输出: [1, 5, 10, 25, 40, 100]// 降序排序
numbers.sort((a, b) => b - a);
console.log(numbers); // 输出: [100, 40, 25, 10, 5, 1]// 对象数组排序
const users = [{ name: "张三", age: 30 },{ name: "李四", age: 24 },{ name: "王五", age: 28 },
];
// 按年龄排序
users.sort((a, b) => a.age - b.age);
console.log(users);
// 输出: [
//   { name: "李四", age: 24 },
//   { name: "王五", age: 28 },
//   { name: "张三", age: 30 }
// ]

注意事项

  • sort() 会改变原数组
  • 默认排序是按字符串 Unicode 码点排序
  • 对数字排序需要提供比较函数,否则 [100, 2, 1] 会被排序为 [1, 100, 2]
  • 对于复杂排序逻辑,可以组合多种条件

8. concat() - 合并数组

使用场景:当你需要将多个数组合并为一个新数组时。

示例代码

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [7, 8, 9];// 合并两个数组
const merged = arr1.concat(arr2);
console.log(merged); // 输出: [1, 2, 3, 4, 5, 6]// 合并多个数组
const mergedAll = arr1.concat(arr2, arr3);
console.log(mergedAll); // 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]// 合并值和数组
const mergedWithValues = arr1.concat(4, [5, 6], 7);
console.log(mergedWithValues); // 输出: [1, 2, 3, 4, 5, 6, 7]

注意事项

  • concat() 不会修改原数组,而是返回一个新数组
  • 可以连接多个数组或值
  • 如果传入的参数是数组,会将其元素添加到结果数组中
  • ES6 中可以使用扩展运算符 [...arr1, ...arr2] 代替

9. slice() - 提取数组片段

使用场景:当你需要从数组中提取部分元素而不修改原数组时。

示例代码

const numbers = [0, 1, 2, 3, 4, 5];// 从索引1到索引3(不包括4)
const sliced1 = numbers.slice(1, 4);
console.log(sliced1); // 输出: [1, 2, 3]// 从索引2到末尾
const sliced2 = numbers.slice(2);
console.log(sliced2); // 输出: [2, 3, 4, 5]// 提取最后两个元素
const sliced3 = numbers.slice(-2);
console.log(sliced3); // 输出: [4, 5]// 复制整个数组
const copy = numbers.slice();
console.log(copy); // 输出: [0, 1, 2, 3, 4, 5]

注意事项

  • slice() 不会修改原数组,而是返回一个新数组
  • 如果省略第二个参数,则提取到数组末尾
  • 可以使用负索引,表示从数组末尾倒数
  • 常用于创建数组的浅拷贝 const copy = arr.slice()

10. splice() - 添加/删除数组元素

使用场景:当你需要在数组中添加或删除元素时。

示例代码

// 删除元素
const numbers = [1, 2, 3, 4, 5];
const removed = numbers.splice(2, 2); // 从索引2开始删除2个元素
console.log(numbers); // 输出: [1, 2, 5]
console.log(removed); // 输出: [3, 4]// 替换元素
const fruits = ["苹果", "香蕉", "橙子", "葡萄"];
fruits.splice(1, 2, "桃子", "西瓜"); // 从索引1开始删除2个元素,并添加新元素
console.log(fruits); // 输出: ["苹果", "桃子", "西瓜", "葡萄"]// 插入元素(不删除)
const colors = ["红", "绿", "蓝"];
colors.splice(1, 0, "黄", "紫"); // 在索引1处插入元素,不删除
console.log(colors); // 输出: ["红", "黄", "紫", "绿", "蓝"]

注意事项

  • splice() 会修改原数组
  • 返回被删除的元素组成的数组
  • 功能强大,可以同时执行删除和添加操作
  • 第一个参数是起始索引,第二个参数是删除元素的个数,后面的参数是要添加的元素

11. includes() - 检查数组是否包含某个元素

使用场景:当你需要检查数组是否包含某个特定值时。

示例代码

const numbers = [1, 2, 3, 4, 5];console.log(numbers.includes(3)); // 输出: true
console.log(numbers.includes(6)); // 输出: false// 从指定索引开始搜索
console.log(numbers.includes(1, 1)); // 输出: false// 检查字符串数组
const fruits = ["苹果", "香蕉", "橙子"];
const hasBanana = fruits.includes("香蕉");
console.log(hasBanana); // 输出: true// 实际应用:权限检查
const userRoles = ["user", "editor"];
const canPublish = userRoles.includes("editor") || userRoles.includes("admin");
console.log(canPublish); // 输出: true

注意事项

  • ES7 (ES2016) 中新增的方法
  • 对于简单类型的值比 indexOf() 更直观
  • 可以检测 NaN,而 indexOf() 不行
  • 第二个参数可以指定开始搜索的位置

12. flat() 和 flatMap() - 数组扁平化

使用场景:当你需要将嵌套数组扁平化为一维数组时。

示例代码

// 扁平化一级嵌套数组
const nestedArray = [1, 2, [3, 4], 5, [6, 7]];
const flattened = nestedArray.flat();
console.log(flattened); // 输出: [1, 2, 3, 4, 5, 6, 7]// 扁平化多级嵌套数组
const deeplyNested = [1, [2, [3, [4, 5]]]];
const flattenedOneLevel = deeplyNested.flat();
console.log(flattenedOneLevel); // 输出: [1, 2, [3, [4, 5]]]const flattenedAll = deeplyNested.flat(Infinity);
console.log(flattenedAll); // 输出: [1, 2, 3, 4, 5]// flatMap():先映射后扁平化
const sentences = ["Hello world", "JavaScript is fun"];
const words = sentences.flatMap((sentence) => sentence.split(" "));
console.log(words); // 输出: ["Hello", "world", "JavaScript", "is", "fun"]

注意事项

  • ES10 (ES2019) 中新增的方法
  • flat() 可以指定扁平化的层级,默认为 1
  • flat(Infinity) 可以完全扁平化任意深度的嵌套数组
  • flatMap() 相当于先执行 map() 然后执行 flat(1),效率更高

13. push() 和 pop() - 栈操作

使用场景:当你需要将数组作为栈使用,进行后进先出(LIFO)操作时。

示例代码

const stack = [];// 添加元素到栈顶(数组末尾)
stack.push("A");
stack.push("B");
stack.push("C");
console.log(stack); // 输出: ["A", "B", "C"]// 移除栈顶元素
const topItem = stack.pop();
console.log(topItem); // 输出: "C"
console.log(stack); // 输出: ["A", "B"]// 实现撤销功能
const history = [];
function performAction(action) {console.log(`执行操作: ${action}`);history.push(action);
}function undo() {const action = history.pop();if (action) {console.log(`撤销操作: ${action}`);} else {console.log("没有操作可以撤销");}
}performAction("创建文件");
performAction("编辑文件");
undo(); // 输出: 撤销操作: 编辑文件
undo(); // 输出: 撤销操作: 创建文件
undo(); // 输出: 没有操作可以撤销

注意事项

  • push() 和 pop() 会修改原数组
  • push() 可以一次添加多个元素 arr.push(1, 2, 3)
  • push() 返回添加元素后数组的新长度
  • pop() 返回被移除的元素,如果数组为空则返回 undefined

14. unshift() 和 shift() - 队列操作

使用场景:当你需要将数组作为队列使用,进行先进先出(FIFO)操作时。

示例代码

const queue = [];// 添加元素到队列末尾
queue.push("A");
queue.push("B");
queue.push("C");
console.log(queue); // 输出: ["A", "B", "C"]// 从队列头部移除元素
const firstItem = queue.shift();
console.log(firstItem); // 输出: "A"
console.log(queue); // 输出: ["B", "C"]// 在数组头部添加元素
queue.unshift("X");
console.log(queue); // 输出: ["X", "B", "C"]// 实际应用:任务队列
const taskQueue = [];function addTask(task) {taskQueue.push(task);console.log(`添加任务: ${task}`);
}function processNextTask() {if (taskQueue.length > 0) {const task = taskQueue.shift();console.log(`处理任务: ${task}`);return task;} else {console.log("没有任务可以处理");return null;}
}addTask("发送邮件");
addTask("更新数据库");
addTask("生成报告");
processNextTask(); // 输出: 处理任务: 发送邮件
processNextTask(); // 输出: 处理任务: 更新数据库

注意事项

  • unshift() 和 shift() 会修改原数组
  • 这些操作在大型数组上可能会比较慢,因为需要移动所有元素
  • unshift() 可以一次添加多个元素 arr.unshift(1, 2, 3)
  • unshift() 返回添加元素后数组的新长度
  • shift() 返回被移除的元素,如果数组为空则返回 undefined

String 字符串

1. split() - 分割字符串

使用场景:当你需要将字符串分割成数组时。

示例代码

// 按空格分割句子
const sentence = "JavaScript 是一门很棒的语言";
const words = sentence.split(" ");
console.log(words); // 输出: ["JavaScript", "是一门很棒的语言"]// 分割CSV数据
const csvData = "张三,25,北京";
const personInfo = csvData.split(",");
console.log(personInfo); // 输出: ["张三", "25", "北京"]

注意事项

  • 如果分隔符是空字符串,则会将字符串分割成单个字符的数组
  • 可以通过第二个参数限制返回数组的最大长度

2. substring() 和 slice() - 提取子字符串

使用场景:当你需要获取字符串的一部分时。

示例代码

const text = "JavaScript编程";// 使用 substring(起始索引, 结束索引)
console.log(text.substring(0, 10)); // 输出: "JavaScript"// 使用 slice(起始索引, 结束索引)
console.log(text.slice(0, 10)); // 输出: "JavaScript"
console.log(text.slice(-3)); // 输出: "编程" (负数索引从后往前数)

注意事项

  • substring() 不接受负索引,而 slice() 接受负索引
  • 如果省略第二个参数,两者都会提取到字符串末尾
  • substring() 会把较小的参数作为开始索引,较大的作为结束索引

3. replace() - 替换字符串

使用场景:当你需要替换字符串中的某些内容时。

示例代码

// 替换第一个匹配项
const text = "我喜欢吃苹果,苹果很好吃";
const newText = text.replace("苹果", "香蕉");
console.log(newText); // 输出: "我喜欢吃香蕉,苹果很好吃"// 使用正则表达式替换所有匹配项
const allReplaced = text.replace(/苹果/g, "香蕉");
console.log(allReplaced); // 输出: "我喜欢吃香蕉,香蕉很好吃"

注意事项

  • replace() 默认只替换第一个匹配项
  • 要替换所有匹配项,需要使用正则表达式和全局标志 g
  • 原字符串不会被修改,而是返回一个新字符串

4. toLowerCase() 和 toUpperCase() - 大小写转换

使用场景:当你需要统一字符串的大小写格式时。

示例代码

const text = "Hello World";// 转换为小写
const lowerCase = text.toLowerCase();
console.log(lowerCase); // 输出: "hello world"// 转换为大写
const upperCase = text.toUpperCase();
console.log(upperCase); // 输出: "HELLO WORLD"// 实际应用:不区分大小写的比较
function compareIgnoreCase(str1, str2) {return str1.toLowerCase() === str2.toLowerCase();
}console.log(compareIgnoreCase("Hello", "hello")); // 输出: true
console.log(compareIgnoreCase("Hello", "world")); // 输出: false

注意事项

  • 原字符串不会被修改,而是返回一个新字符串
  • 这些方法只影响字母字符,数字和符号不受影响
  • 某些语言可能需要特殊的本地化处理

5. trim() 和其变体 - 去除空白

使用场景:当你需要删除字符串开头和结尾的空白字符时。

示例代码

const text = "   Hello World   ";// 删除首尾空白
const trimmed = text.trim();
console.log(trimmed); // 输出: "Hello World"// 仅删除开头空白
const trimmedStart = text.trimStart(); // 也可以用 trimLeft()
console.log(trimmedStart); // 输出: "Hello World   "// 仅删除结尾空白
const trimmedEnd = text.trimEnd(); // 也可以用 trimRight()
console.log(trimmedEnd); // 输出: "   Hello World"// 实际应用:表单输入清理
function cleanInput(input) {return input.trim();
}console.log(cleanInput("  user@example.com  ")); // 输出: "user@example.com"

注意事项

  • 原字符串不会被修改,而是返回一个新字符串
  • trimStart() 和 trimEnd() 是 ES2019 新增的方法
  • 空白字符包括空格、制表符、换行符等
  • 用户输入验证前通常应该先 trim()

6. padStart() 和 padEnd() - 填充字符串

使用场景:当你需要将字符串填充到指定长度时。

示例代码

// 数字前面补零
const num = "5";
const paddedNum = num.padStart(2, "0");
console.log(paddedNum); // 输出: "05"// 信用卡号码遮蔽
const creditCard = "1234567890123456";
const lastFour = creditCard.slice(-4);
const masked = lastFour.padStart(creditCard.length, "*");
console.log(masked); // 输出: "************3456"// 右侧填充
const text = "Hello";
const paddedRight = text.padEnd(10, "-");
console.log(paddedRight); // 输出: "Hello-----"// 实际应用:表格对齐
const data = ["名称", "价格", "库存"];
const formatted = data.map((item) => item.padEnd(10, " "));
console.log(formatted.join(" | ")); // 输出: "名称       | 价格       | 库存       "

注意事项

  • ES8 (ES2017) 中新增的方法
  • 如果原字符串长度已经大于或等于指定长度,则返回原字符串
  • 填充字符串如果过长会被截断

7. includes(), startsWith() 和 endsWith() - 字符串检查

使用场景:当你需要检查字符串是否包含、以某内容开头或结尾时。

示例代码

const sentence = "JavaScript是Web开发中最流行的语言之一";// 检查是否包含某个子字符串
console.log(sentence.includes("Web")); // 输出: true
console.log(sentence.includes("Python")); // 输出: false// 检查是否以某个子字符串开头
console.log(sentence.startsWith("JavaScript")); // 输出: true
console.log(sentence.startsWith("Web", 10)); // 输出: true (从索引10开始检查)// 检查是否以某个子字符串结尾
console.log(sentence.endsWith("之一")); // 输出: true
console.log(sentence.endsWith("JavaScript", 10)); // 输出: true (检查前10个字符)// 实际应用:文件类型检查
function isImageFile(filename) {return (filename.toLowerCase().endsWith(".jpg") ||filename.toLowerCase().endsWith(".png") ||filename.toLowerCase().endsWith(".gif"));
}console.log(isImageFile("photo.JPG")); // 输出: true
console.log(isImageFile("document.pdf")); // 输出: false

注意事项

  • ES6 中新增的方法
  • 这些方法都可以指定开始搜索的位置
  • 区分大小写,如果需要不区分大小写,可以先转换为小写
  • 比 indexOf() 更直观和语义化

8. repeat() - 重复字符串

使用场景:当你需要将字符串重复多次时。

示例代码

// 简单重复
const star = "*";
console.log(star.repeat(5)); // 输出: "*****"// 创建分隔线
console.log("-".repeat(20)); // 输出: "--------------------"// 缩进处理
function indent(level) {return " ".repeat(level * 2);
}const code ="function hello() {\n" + indent(1) + "console.log('Hello');\n" + "}";
console.log(code);
// 输出:
// function hello() {
//   console.log('Hello');
// }// 实际应用:简单进度条
function progressBar(progress, total) {const percentage = Math.floor((progress / total) * 10);return ("[" +"=".repeat(percentage) +" ".repeat(10 - percentage) +"] " +percentage * 10 +"%");
}console.log(progressBar(3, 10)); // 输出: "[===       ] 30%"
console.log(progressBar(7, 10)); // 输出: "[=======   ] 70%"

注意事项

  • ES6 中新增的方法
  • 参数必须是正整数,否则会抛出错误
  • 如果参数为 0,则返回空字符串

9. charAt() 和 charCodeAt() - 字符处理

使用场景:当你需要处理字符串中的单个字符时。

示例代码

const text = "Hello, 世界!";// 获取指定位置的字符
console.log(text.charAt(0)); // 输出: "H"
console.log(text.charAt(7)); // 输出: "世"// 获取指定位置字符的 Unicode 编码
console.log(text.charCodeAt(0)); // 输出: 72 (H的Unicode值)
console.log(text.charCodeAt(7)); // 输出: 19990 (世的Unicode值)// 获取完整的 Unicode 码点(支持表情符号等)
console.log("😀".codePointAt(0)); // 输出: 128512// 实际应用:简单加密
function simpleEncrypt(text, key) {return Array.from(text).map((char) => String.fromCharCode(char.charCodeAt(0) + key)).join("");
}function simpleDecrypt(encrypted, key) {return Array.from(encrypted).map((char) => String.fromCharCode(char.charCodeAt(0) - key)).join("");
}const original = "Hello";
const encrypted = simpleEncrypt(original, 5);
console.log(encrypted); // 输出加密后的文本
console.log(simpleDecrypt(encrypted, 5)); // 输出: "Hello"

注意事项

  • charAt() 总是返回一个字符,如果索引超出范围则返回空字符串
  • charCodeAt() 返回 0 到 65535 之间的整数,表示 UTF-16 编码
  • 对于 Unicode 码点大于 0xFFFF 的字符(如表情符号),应该使用 codePointAt()
  • ES6 可以使用方括号表示法 text[0] 访问字符,但索引超出时返回 undefined

10. concat() - 连接字符串

使用场景:当你需要连接多个字符串时。

示例代码

const firstName = "张";
const lastName = "三";// 连接两个字符串
const fullName = firstName.concat(lastName);
console.log(fullName); // 输出: "张三"// 连接多个字符串
const greeting = "你好, ".concat(firstName,lastName,"!"," 欢迎访问我们的网站。"
);
console.log(greeting); // 输出: "你好, 张三! 欢迎访问我们的网站。"// 等价的 + 操作符
const greetingWithPlus ="你好, " + firstName + lastName + "!" + " 欢迎访问我们的网站。";
console.log(greetingWithPlus); // 输出: "你好, 张三! 欢迎访问我们的网站。"

注意事项

  • 原字符串不会被修改,而是返回一个新字符串
  • 虽然 concat() 可以连接多个字符串,但在现代 JavaScript 中,通常使用模板字符串或 + 操作符更常见
  • 模板字符串通常更易读:`你好, f i r s t N a m e {firstName} firstName{lastName}! 欢迎访问我们的网站。`

11. match() 和 matchAll() - 正则表达式匹配

使用场景:当你需要使用正则表达式查找字符串中的匹配项时。

示例代码

// 使用 match() 找到所有匹配项
const text = "我的电话号码是 13912345678 和 13887654321";
const phoneMatches = text.match(/1\d{10}/g);
console.log(phoneMatches); // 输出: ["13912345678", "13887654321"]// 获取捕获组
const dateText = "今天是 2023-10-15,明天是 2023-10-16";
const dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
const match = dateText.match(dateRegex);
console.log(match[0]); // 输出: "2023-10-15" (完整匹配)
console.log(match[1]); // 输出: "2023" (第一个捕获组)
console.log(match[2]); // 输出: "10" (第二个捕获组)
console.log(match[3]); // 输出: "15" (第三个捕获组)// 使用 matchAll() 获取所有匹配和捕获组
const text2 = "张三的生日是 1990-01-15,李四的生日是 1985-07-22";
const dateRegex2 = /(\w+)的生日是 (\d{4})-(\d{2})-(\d{2})/g;
const matches = [...text2.matchAll(dateRegex2)];matches.forEach((match) => {console.log(`姓名: ${match[1]}, 出生年: ${match[2]}, 月: ${match[3]}, 日: ${match[4]}`);
});
// 输出:
// 姓名: 张三, 出生年: 1990, 月: 01, 日: 15
// 姓名: 李四, 出生年: 1985, 月: 07, 日: 22

注意事项

  • match() 与不带 g 标志的正则表达式使用时返回详细信息(包括捕获组)
  • match() 与带 g 标志的正则表达式使用时返回所有匹配的数组,但不包含捕获组
  • matchAll() 是 ES2020 新增的方法,返回一个迭代器,需要使用 for…of 或扩展运算符消费
  • matchAll() 同时提供匹配项和捕获组,非常适合复杂的正则匹配需求

12. search() - 查找字符串位置

使用场景:当你需要查找字符串中某个模式第一次出现的位置时。

示例代码

const text = "JavaScript是一门强大的编程语言";// 查找字符串位置
const position = text.search("强大");
console.log(position); // 输出: 13// 使用正则表达式
const digitPosition = "abc123def".search(/\d+/);
console.log(digitPosition); // 输出: 3// 查找不存在的内容
const notFound = text.search("Python");
console.log(notFound); // 输出: -1// 不区分大小写的搜索
const caseInsensitive = "Hello World".search(/world/i);
console.log(caseInsensitive); // 输出: 6

注意事项

  • 返回第一个匹配的位置,如果没有找到则返回 -1
  • 只能接受正则表达式或可以转换为正则表达式的参数
  • 与 indexOf() 类似,但 search() 可以使用更复杂的正则表达式模式
  • 不支持全局搜索,总是返回第一个匹配项的位置

Object 对象

1. Object.keys() - 获取对象的所有键

使用场景:当你需要获取对象的所有属性名时。

示例代码

const person = {name: "张三",age: 30,city: "上海",
};const keys = Object.keys(person);
console.log(keys); // 输出: ["name", "age", "city"]// 结合 forEach 遍历对象
Object.keys(person).forEach((key) => {console.log(`${key}: ${person[key]}`);
});
// 输出:
// name: 张三
// age: 30
// city: 上海

注意事项

  • 只返回对象自身的可枚举属性
  • 返回的数组顺序与属性在对象中的顺序一致
  • 可以用于检查对象是否为空:Object.keys(obj).length === 0

2. Object.values() - 获取对象的所有值

使用场景:当你只关心对象的属性值而不关心属性名时。

示例代码

const person = {name: "张三",age: 30,city: "上海",
};const values = Object.values(person);
console.log(values); // 输出: ["张三", 30, "上海"]// 计算对象中数值属性的总和
const scores = { math: 95, english: 88, history: 76 };
const total = Object.values(scores).reduce((sum, score) => sum + score, 0);
console.log(total); // 输出: 259

注意事项

  • 只返回对象自身的可枚举属性的值
  • ES2017 (ES8) 中新增的方法,注意兼容性

3. Object.entries() - 获取键值对数组

使用场景:当你需要同时操作对象的键和值时。

示例代码

const person = {name: "张三",age: 30,city: "上海",
};const entries = Object.entries(person);
console.log(entries);
// 输出: [["name", "张三"], ["age", 30], ["city", "上海"]]// 遍历键值对
Object.entries(person).forEach(([key, value]) => {console.log(`${key}: ${value}`);
});// 转换为Map对象
const personMap = new Map(Object.entries(person));
console.log(personMap.get("name")); // 输出: "张三"

注意事项

  • 只返回对象自身的可枚举属性的键值对
  • ES2017 (ES8) 中新增的方法,注意兼容性
  • 常用于对象到 Map 的转换

4. Object.assign() - 合并对象

使用场景:当你需要将一个或多个源对象的属性复制到目标对象时。

示例代码

// 合并对象
const target = { a: 1, b: 2 };
const source1 = { b: 3, c: 4 };
const source2 = { c: 5, d: 6 };const result = Object.assign(target, source1, source2);
console.log(target); // 输出: { a: 1, b: 3, c: 5, d: 6 }
console.log(result === target); // 输出: true (修改的是同一个对象)// 创建新对象而不修改原对象
const original = { a: 1, b: 2 };
const copy = Object.assign({}, original, { c: 3 });
console.log(original); // 输出: { a: 1, b: 2 }
console.log(copy); // 输出: { a: 1, b: 2, c: 3 }// 默认值设置
function processOptions(options) {const defaults = {timeout: 1000,cache: true,silent: false,};return Object.assign({}, defaults, options);
}console.log(processOptions({ timeout: 2000 }));
// 输出: { timeout: 2000, cache: true, silent: false }

注意事项

  • 修改目标对象并返回它
  • 如果有同名属性,后面的会覆盖前面的
  • 只复制可枚举属性
  • 执行的是浅拷贝,不会克隆嵌套对象
  • ES6 新增方法,现代开发中可以使用对象展开运算符替代:{...obj1, ...obj2}

5. Object.create() - 创建新对象

使用场景:当你需要创建一个新对象,并指定其原型对象时。

示例代码

// 使用现有对象作为新对象的原型
const person = {isHuman: true,printInfo: function () {console.log(`我叫${this.name},我是${this.isHuman ? "人类" : "非人类"}`);},
};const student = Object.create(person);
student.name = "小明"; // 添加属性
student.isHuman = true; // 覆盖继承的属性
student.printInfo(); // 输出: "我叫小明,我是人类"// 使用null作为原型创建无原型对象
const noProto = Object.create(null);
console.log(noProto.toString); // 输出: undefined (没有继承Object.prototype方法)// 创建对象并定义属性
const config = Object.create(null, {debug: {value: true,writable: false,enumerable: true,},version: {value: "1.0.0",enumerable: true,},
});console.log(config.debug); // 输出: true
console.log(config.version); // 输出: "1.0.0"

注意事项

  • 可以指定新对象的原型对象
  • 用 Object.create(null) 创建的对象没有继承任何属性和方法
  • 可以通过第二个参数定义对象的属性及其特性
  • 是实现对象继承的有效方式

6. Object.freeze() 和 Object.seal() - 对象不可变性

使用场景:当你需要防止对象被修改时。

示例代码

// Object.freeze() - 完全冻结对象
const frozenObj = {prop: 42,nested: { value: "可以修改" },
};Object.freeze(frozenObj);// 尝试修改
frozenObj.prop = 100; // 不起作用
frozenObj.newProp = "新属性"; // 不起作用
delete frozenObj.prop; // 不起作用console.log(frozenObj.prop); // 输出: 42
console.log(frozenObj.newProp); // 输出: undefined// 注意:嵌套对象不受影响
frozenObj.nested.value = "已修改";
console.log(frozenObj.nested.value); // 输出: "已修改"// Object.seal() - 封闭对象(可以修改现有属性值)
const sealedObj = { x: 1, y: 2 };
Object.seal(sealedObj);sealedObj.x = 10; // 可以修改
sealedObj.z = 3; // 不起作用
delete sealedObj.y; // 不起作用console.log(sealedObj); // 输出: { x: 10, y: 2 }// 检查对象状态
console.log(Object.isFrozen(frozenObj)); // 输出: true
console.log(Object.isSealed(sealedObj)); // 输出: true

注意事项

  • Object.freeze() 使对象不可修改、不可添加/删除属性、不可修改属性特性
  • Object.seal() 使对象不可添加/删除属性,但可以修改现有属性值
  • 这些方法只影响对象的顶层属性,嵌套对象不受影响
  • 在严格模式下,尝试修改冻结/封闭对象会抛出 TypeError

7. Object.fromEntries() - 将键值对转换为对象

使用场景:当你有一个键值对数组或 Map 对象,需要转换为普通对象时。

示例代码

// 从键值对数组创建对象
const entries = [["name", "张三"],["age", 30],["city", "北京"],
];const person = Object.fromEntries(entries);
console.log(person); // 输出: { name: '张三', age: 30, city: '北京' }// 从Map创建对象
const map = new Map();
map.set("name", "李四");
map.set("age", 25);const mapObject = Object.fromEntries(map);
console.log(mapObject); // 输出: { name: '李四', age: 25 }// 实际应用:URL查询参数转对象
const queryString = "name=张三&age=30&city=北京";
const params = new URLSearchParams(queryString);
const paramsObject = Object.fromEntries(params);console.log(paramsObject); // 输出: { name: '张三', age: '30', city: '北京' }

注意事项

  • ES2019 (ES10) 新增方法
  • 是 Object.entries() 的逆操作
  • 接受任何实现了迭代器接口的对象,比如数组、Map 等
  • 对于重复的键,后面的值会覆盖前面的值

8. Object.defineProperty() 和 Object.defineProperties() - 定义属性

使用场景:当你需要精确地定义对象属性及其特性时。

示例代码

// 定义单个属性
const product = {};Object.defineProperty(product, "name", {value: "手机",writable: false, // 不可修改enumerable: true, // 可枚举configurable: false, // 不可删除或重新配置
});Object.defineProperty(product, "price", {value: 1999,writable: true,enumerable: true,
});// 尝试修改
product.name = "笔记本"; // 不起作用
product.price = 2999; // 可以修改console.log(product.name); // 输出: "手机"
console.log(product.price); // 输出: 2999// 定义多个属性
const user = {};Object.defineProperties(user, {firstName: {value: "张",writable: true,enumerable: true,},lastName: {value: "三",writable: true,enumerable: true,},fullName: {get() {return `${this.firstName}${this.lastName}`;},enumerable: true,},age: {value: 30,writable: true,enumerable: false, // 不会在循环中显示},
});console.log(user.fullName); // 输出: "张三"
console.log(Object.keys(user)); // 输出: ["firstName", "lastName", "fullName"] (不包含age)

注意事项

  • 允许精确控制属性特性:可写性(writable)、可枚举性(enumerable)、可配置性(configurable)
  • 可以定义访问器属性(getter/setter)
  • 默认情况下,通过这些方法定义的属性都是不可写、不可枚举、不可配置的
  • 可以使用 Object.getOwnPropertyDescriptor() 检查属性特性

9. Object.getPrototypeOf() 和 Object.setPrototypeOf() - 原型操作

使用场景:当你需要获取或设置对象的原型时。

示例代码

// 获取对象的原型
const arr = [];
const proto = Object.getPrototypeOf(arr);
console.log(proto === Array.prototype); // 输出: true// 设置对象的原型
const animal = {speak() {console.log(`${this.name}发出声音`);},
};const dog = {name: "旺财",bark() {console.log("汪汪!");},
};// 设置dog的原型为animal
Object.setPrototypeOf(dog, animal);dog.speak(); // 输出: "旺财发出声音"
dog.bark(); // 输出: "汪汪!"// 检查原型链
function isInPrototypeChain(obj, constructor) {let proto = Object.getPrototypeOf(obj);while (proto !== null) {if (proto === constructor.prototype) return true;proto = Object.getPrototypeOf(proto);}return false;
}console.log(isInPrototypeChain([], Array)); // 输出: true
console.log(isInPrototypeChain({}, Array)); // 输出: false

注意事项

  • Object.setPrototypeOf() 会影响性能,应避免频繁使用
  • 更好的方式是使用 Object.create() 创建具有特定原型的新对象
  • 在现代 JavaScript 中,可以使用 __proto__ 属性,但它已被废弃,不推荐使用
  • 这些方法主要用于框架和库开发,普通应用开发少用

10. Object.is() - 值比较

使用场景:当你需要比较两个值是否相同,包括处理一些特殊情况时。

示例代码

// 基本比较
console.log(Object.is(5, 5)); // 输出: true
console.log(Object.is("hello", "hello")); // 输出: true
console.log(Object.is([], [])); // 输出: false (不同对象)// 与 === 运算符的区别
console.log(+0 === -0); // 输出: true
console.log(Object.is(+0, -0)); // 输出: falseconsole.log(NaN === NaN); // 输出: false
console.log(Object.is(NaN, NaN)); // 输出: true// 对象引用
const obj = { a: 1 };
const sameObj = obj;
console.log(Object.is(obj, sameObj)); // 输出: true// 实际应用:React的状态比较
function checkIfStateChanged(prevState, nextState) {// 浅比较对象中的每个属性if (Object.keys(prevState).length !== Object.keys(nextState).length) {return true;}return Object.keys(prevState).some((key) => !Object.is(prevState[key], nextState[key]));
}const oldState = { count: 5, name: "张三" };
const newState = { count: 5, name: "李四" };
console.log(checkIfStateChanged(oldState, newState)); // 输出: true

注意事项

  • ES6 新增方法
  • 与 === 运算符的主要区别:
    • Object.is(NaN, NaN) 返回 true
    • Object.is(+0, -0) 返回 false
  • 对于对象仍然是比较引用,不比较内容
  • 适用于需要精确比较的场景,如状态管理

Date 日期

1. new Date() - 创建日期对象

使用场景:当你需要处理日期和时间时。

示例代码

// 创建当前日期时间的对象
const now = new Date();
console.log(now); // 输出当前时间,如: Tue Oct 12 2023 15:30:45 GMT+0800// 创建特定日期的对象
const christmas = new Date(2023, 11, 25); // 月份是0-11,所以12月是11
console.log(christmas); // 输出: Mon Dec 25 2023 00:00:00 GMT+0800// 从时间戳创建日期对象
const timestamp = 1609459200000; // 2021-01-01 00:00:00
const newYear = new Date(timestamp);
console.log(newYear); // 输出: Fri Jan 01 2021 00:00:00 GMT+0800

注意事项

  • JavaScript 中月份从 0 开始计数(0 表示一月,11 表示十二月)
  • 日期对象创建后,可以使用各种方法获取或设置其组成部分

2. 格式化日期

使用场景:当你需要以特定格式显示日期时。

示例代码

const today = new Date();// 获取各部分
const year = today.getFullYear();
const month = today.getMonth() + 1; // 月份需要+1,因为从0开始
const day = today.getDate();
const hours = today.getHours();
const minutes = today.getMinutes();
const seconds = today.getSeconds();// 自定义格式化
const formattedDate = `${year}${month}${day}${hours}:${minutes}:${seconds}`;
console.log(formattedDate); // 输出类似: 2023年10月12日 15:30:45// 使用 toLocaleDateString 方法
const localDate = today.toLocaleDateString("zh-CN", {year: "numeric",month: "long",day: "numeric",weekday: "long",
});
console.log(localDate); // 输出类似: 2023年10月12日星期四

注意事项

  • 获取月份时记得加 1,因为月份从 0 开始
  • 为了保持格式一致,可能需要对个位数补零
  • toLocaleDateString 方法提供了丰富的本地化格式选项

3. 日期计算

使用场景:当你需要计算日期差异或进行日期操作时。

示例代码

// 计算两个日期之间的天数差
const date1 = new Date("2023-01-01");
const date2 = new Date("2023-01-15");
const diffTime = Math.abs(date2 - date1);
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
console.log(`相差 ${diffDays}`); // 输出: 相差 14 天// 添加天数
const today = new Date();
const futureDate = new Date(today);
futureDate.setDate(today.getDate() + 30);
console.log(`30天后是: ${futureDate.toLocaleDateString()}`);

注意事项

  • 日期对象可以相减,结果是毫秒数
  • setDate(), setMonth() 等方法可以用于修改日期
  • 注意处理月末日期,如 1 月 31 日加一个月可能变成 3 月某一天

4. 日期比较

使用场景:当你需要比较两个日期的先后或是否相等时。

示例代码

// 比较日期的先后
const date1 = new Date("2023-05-10");
const date2 = new Date("2023-10-15");
const date3 = new Date("2023-05-10");// 使用比较运算符
console.log(date1 < date2); // 输出: true (5月早于10月)
console.log(date1 > date2); // 输出: false// 检查日期是否相等
console.log(date1.getTime() === date3.getTime()); // 输出: true
console.log(date1 === date3); // 输出: false (两个不同的对象)// 判断某个日期是否在两个日期之间
function isBetween(date, start, end) {return date >= start && date <= end;
}const checkDate = new Date("2023-06-15");
console.log(isBetween(checkDate, date1, date2)); // 输出: true// 判断是否为同一天
function isSameDay(date1, date2) {return (date1.getFullYear() === date2.getFullYear() &&date1.getMonth() === date2.getMonth() &&date1.getDate() === date2.getDate());
}console.log(isSameDay(new Date("2023-05-10T10:30:00"), new Date("2023-05-10T18:15:00"))
); // 输出: true

注意事项

  • 日期对象可以直接用 <, >, <=, >= 比较
  • 不能用 == 或 === 直接比较日期对象相等,因为它们是引用类型
  • 比较日期相等应使用 getTime() 方法或自定义方法

5. 获取特定日期部分

使用场景:当你需要获取日期的特定部分(年、月、日、星期几等)时。

示例代码

const date = new Date("2023-05-20T15:30:45.500Z");// 获取年、月、日
console.log(date.getFullYear()); // 输出: 2023
console.log(date.getMonth()); // 输出: 4 (5月)
console.log(date.getDate()); // 输出: 20// 获取时、分、秒、毫秒
console.log(date.getHours()); // 输出: 23 (假设东八区)
console.log(date.getMinutes()); // 输出: 30
console.log(date.getSeconds()); // 输出: 45
console.log(date.getMilliseconds()); // 输出: 500// 获取星期几 (0-6,0代表周日)
console.log(date.getDay()); // 输出: 6 (周六)// 获取时间戳(毫秒数)
console.log(date.getTime()); // 输出: 1684596645500// 实际应用:获取本月天数
function getDaysInMonth(year, month) {// month传入的是1-12,需要转换为0-11return new Date(year, month, 0).getDate();
}console.log(getDaysInMonth(2023, 2)); // 输出: 28 (2023年2月有28天)
console.log(getDaysInMonth(2024, 2)); // 输出: 29 (闰年)

注意事项

  • get 方法返回本地时间的部分,有对应的 getUTC 方法返回 UTC 时间的部分
  • getMonth() 返回 0-11,代表 1-12 月
  • getDay() 返回 0-6,代表周日-周六

6. 设置特定日期部分

使用场景:当你需要修改日期的特定部分时。

示例代码

// 创建日期
let date = new Date("2023-05-20");// 设置年、月、日
date.setFullYear(2024);
console.log(date); // 输出: Mon May 20 2024 ...date.setMonth(0); // 设置为1月
console.log(date); // 输出: Sat Jan 20 2024 ...date.setDate(15);
console.log(date); // 输出: Mon Jan 15 2024 ...// 设置时、分、秒、毫秒
date.setHours(10);
date.setMinutes(30);
date.setSeconds(0);
date.setMilliseconds(0);
console.log(date); // 输出: Mon Jan 15 2024 10:30:00 ...// 使用毫秒数设置日期
date.setTime(1672502400000); // 2023-01-01 00:00:00
console.log(date); // 输出: Sun Jan 01 2023 00:00:00 ...// 实际应用:将日期设置为本月最后一天
function setToLastDayOfMonth(date) {// 设置为下个月的第0天,即本月最后一天date.setMonth(date.getMonth() + 1, 0);return date;
}const someDate = new Date("2023-05-15");
setToLastDayOfMonth(someDate);
console.log(someDate); // 输出: Wed May 31 2023 ...

注意事项

  • set 方法会修改原日期对象
  • 设置超出范围的值会导致日期自动调整(如设置 2 月 31 日会变成 3 月某一天)
  • 有对应的 setUTC 方法设置 UTC 时间的部分

7. 时区和国际化处理

使用场景:当你需要处理不同时区的日期或本地化显示日期时。

示例代码

// 获取带时区的日期字符串
const date = new Date("2023-05-20T10:30:00Z");// ISO 格式(适合数据交换)
console.log(date.toISOString()); // 输出: 2023-05-20T10:30:00.000Z// 获取时区偏移量(分钟)
const timezoneOffset = date.getTimezoneOffset();
console.log(timezoneOffset); // 输出: -480 (东八区为-480分钟,即-8小时)// 本地化日期格式
console.log(date.toLocaleDateString("zh-CN")); // 输出: 2023/5/20
console.log(date.toLocaleDateString("en-US")); // 输出: 5/20/2023
console.log(date.toLocaleDateString("de-DE")); // 输出: 20.5.2023// 本地化时间格式
console.log(date.toLocaleTimeString("zh-CN")); // 输出: 18:30:00
console.log(date.toLocaleTimeString("en-US")); // 输出: 6:30:00 PM// 完整的本地化日期和时间格式
console.log(date.toLocaleString("zh-CN")); // 输出: 2023/5/20 18:30:00
console.log(date.toLocaleString("en-US")); // 输出: 5/20/2023, 6:30:00 PM// 高级格式化
console.log(date.toLocaleString("zh-CN", {weekday: "long",year: "numeric",month: "long",day: "numeric",hour: "2-digit",minute: "2-digit",second: "2-digit",timeZoneName: "long",})
); // 输出: 2023年5月20日星期六 18:30:00 中国标准时间

注意事项

  • toISOString() 总是返回 UTC 时间的字符串
  • 时区偏移量以分钟为单位,正值表示比 UTC 早,负值表示比 UTC 晚
  • Intl.DateTimeFormat 提供了更强大的国际化日期格式化能力

Math 数学

1. Math.random() - 生成随机数

使用场景:当你需要生成随机数或随机选择时。

示例代码

// 生成0到1之间的随机数(不包括1)
const random = Math.random();
console.log(random); // 输出例如: 0.7589021623732578// 生成1到10之间的随机整数
const randomInt = Math.floor(Math.random() * 10) + 1;
console.log(randomInt); // 输出1到10之间的整数// 从数组中随机选择一个元素
const fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"];
const randomIndex = Math.floor(Math.random() * fruits.length);
const randomFruit = fruits[randomIndex];
console.log(`随机水果: ${randomFruit}`);

注意事项

  • Math.random() 生成的是伪随机数,不适用于加密场景
  • 生成范围内随机整数的公式:Math.floor(Math.random() * (max - min + 1)) + min

2. Math.round(), Math.floor(), Math.ceil() - 数字取整

使用场景:当你需要对小数进行取整时。

示例代码

const num = 4.6;// 四舍五入
console.log(Math.round(num)); // 输出: 5
console.log(Math.round(4.4)); // 输出: 4// 向下取整(不大于原数的最大整数)
console.log(Math.floor(num)); // 输出: 4
console.log(Math.floor(-4.6)); // 输出: -5// 向上取整(不小于原数的最小整数)
console.log(Math.ceil(num)); // 输出: 5
console.log(Math.ceil(-4.6)); // 输出: -4

注意事项

  • 注意负数的情况,Math.floor(-4.6) 等于 -5,而不是 -4
  • 金融计算中四舍五入可能需要特殊处理,避免二进制浮点数精度问题

3. Math.max() 和 Math.min() - 最大值和最小值

使用场景:当你需要找出一组数字中的最大或最小值时。

示例代码

// 找出最大值
console.log(Math.max(5, 10, 3, 8, 6)); // 输出: 10// 找出最小值
console.log(Math.min(5, 10, 3, 8, 6)); // 输出: 3// 结合展开运算符找出数组中的最大值
const numbers = [5, 10, 3, 8, 6];
console.log(Math.max(...numbers)); // 输出: 10// 实际应用:确保值在范围内
function clamp(value, min, max) {return Math.min(Math.max(value, min), max);
}
console.log(clamp(15, 0, 10)); // 输出: 10
console.log(clamp(-5, 0, 10)); // 输出: 0
console.log(clamp(5, 0, 10)); // 输出: 5

注意事项

  • 如果传入非数字参数,返回 NaN
  • 不传参数时,Math.max() 返回 -Infinity,Math.min() 返回 Infinity
  • 要处理数组,需要使用扩展运算符 (…)

4. Math.abs() - 绝对值

使用场景:当你需要获取数字的绝对值(非负值)时。

示例代码

// 基本用法
console.log(Math.abs(5)); // 输出: 5
console.log(Math.abs(-5)); // 输出: 5
console.log(Math.abs(0)); // 输出: 0// 计算两个数的差值(不关心谁大谁小)
function difference(a, b) {return Math.abs(a - b);
}console.log(difference(10, 5)); // 输出: 5
console.log(difference(5, 10)); // 输出: 5// 判断两个浮点数是否近似相等
function isApproximatelyEqual(a, b, epsilon = 0.0001) {return Math.abs(a - b) < epsilon;
}console.log(isApproximatelyEqual(0.1 + 0.2, 0.3)); // 输出: true

注意事项

  • 传入非数字参数时,会尝试将其转换为数字
  • 如果参数无法转换为数字,返回 NaN
  • 用于处理方向无关的距离计算

5. Math.pow() 和 Math.sqrt() - 幂运算和平方根

使用场景:当你需要计算幂或平方根时。

示例代码

// 幂运算(x的y次方)
console.log(Math.pow(2, 3)); // 输出: 8 (2的3次方)
console.log(Math.pow(5, 2)); // 输出: 25 (5的平方)
console.log(Math.pow(4, 0.5)); // 输出: 2 (4的平方根)
console.log(Math.pow(2, -1)); // 输出: 0.5 (2的-1次方,即1/2)// 平方根
console.log(Math.sqrt(9)); // 输出: 3
console.log(Math.sqrt(2)); // 输出: 1.4142135623730951
console.log(Math.sqrt(-1)); // 输出: NaN (负数的平方根在实数范围内不存在)// 计算直角三角形斜边长度(勾股定理)
function calculateHypotenuse(a, b) {return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));// 或者使用 ES6 的 ** 运算符:return Math.sqrt(a ** 2 + b ** 2);
}console.log(calculateHypotenuse(3, 4)); // 输出: 5

注意事项

  • ES6 引入了 ** 运算符,可以替代 Math.pow(),例如 2 ** 3 等同于 Math.pow(2, 3)
  • Math.sqrt() 只能计算正数的平方根,对于负数返回 NaN
  • 可以使用 Math.pow(x, 1/n) 计算 x 的 n 次方根

6. Math.sin(), Math.cos(), Math.tan() - 三角函数

使用场景:当你需要进行三角函数计算或处理角度和坐标时。

示例代码

// 基本三角函数(参数为弧度)
console.log(Math.sin(Math.PI / 2)); // 输出: 1 (90度的正弦值)
console.log(Math.cos(Math.PI)); // 输出: -1 (180度的余弦值)
console.log(Math.tan(Math.PI / 4)); // 输出: 0.9999999999999999 (接近1,45度的正切值)// 度数转弧度
function toRadians(degrees) {return degrees * (Math.PI / 180);
}// 弧度转度数
function toDegrees(radians) {return radians * (180 / Math.PI);
}console.log(Math.sin(toRadians(90))); // 输出: 1
console.log(toDegrees(Math.PI)); // 输出: 180// 在圆上计算点的坐标
function getPointOnCircle(centerX, centerY, radius, angleInDegrees) {const angleInRadians = toRadians(angleInDegrees);return {x: centerX + radius * Math.cos(angleInRadians),y: centerY + radius * Math.sin(angleInRadians),};
}const point = getPointOnCircle(100, 100, 50, 60);
console.log(point); // 输出: { x: 125, y: 143.3 } (大约)

注意事项

  • 三角函数的参数是弧度,不是度数(1 弧度 ≈ 57.3 度,1 度 = π/180 弧度)
  • Math.PI 常量代表圆周率 π
  • JavaScript 还提供了反三角函数:Math.asin(), Math.acos(), Math.atan()

7. Math.log(), Math.exp() - 对数和指数函数

使用场景:当你需要计算自然对数或指数时。

示例代码

// 自然对数(以e为底)
console.log(Math.log(Math.E)); // 输出: 1 (e的自然对数等于1)
console.log(Math.log(1)); // 输出: 0 (任何底数的0次方等于1,所以1的对数等于0)
console.log(Math.log(10)); // 输出: 2.302585092994046// 以10为底的对数
console.log(Math.log10(100)); // 输出: 2
console.log(Math.log10(1000)); // 输出: 3// 以2为底的对数
console.log(Math.log2(8)); // 输出: 3
console.log(Math.log2(16)); // 输出: 4// 自然指数(e的n次方)
console.log(Math.exp(1)); // 输出: 2.718281828459045 (e的1次方)
console.log(Math.exp(2)); // 输出: 7.3890560989306495 (e的2次方)
console.log(Math.exp(0)); // 输出: 1// 使用场景:复利计算
function calculateCompoundInterest(principal, rate, time) {// A = P * e^(rt)return principal * Math.exp(rate * time);
}console.log(calculateCompoundInterest(1000, 0.05, 10)); // 输出: 1648.7212707001282

注意事项

  • Math.log() 是自然对数(以 e 为底)
  • Math.log10() 和 Math.log2() 分别是以 10 和 2 为底的对数
  • Math.E 常量表示自然对数的底数 e (约等于 2.718)
  • 对数用于处理指数增长的数据,如复利、人口增长等

8. Math.sign(), Math.trunc(), Math.fround() - ES6 新增函数

使用场景:当你需要确定数字的符号、截断小数部分或获取单精度浮点数表示时。

示例代码

// Math.sign() - 返回数字的符号
console.log(Math.sign(10)); // 输出: 1
console.log(Math.sign(-10)); // 输出: -1
console.log(Math.sign(0)); // 输出: 0
console.log(Math.sign(-0)); // 输出: -0
console.log(Math.sign(NaN)); // 输出: NaN// Math.trunc() - 删除小数部分(与floor不同,不会舍入)
console.log(Math.trunc(3.7)); // 输出: 3
console.log(Math.trunc(-3.7)); // 输出: -3
console.log(Math.floor(-3.7)); // 输出: -4 (向下舍入)// Math.fround() - 返回最接近的32位单精度浮点数表示
console.log(Math.fround(1.337)); // 输出: 1.3370000123977661
console.log(Math.fround(1.5)); // 输出: 1.5// 使用Math.sign()简化代码
function getMovementDirection(velocity) {switch (Math.sign(velocity)) {case 1:return "向前";case -1:return "向后";case 0:return "静止";default:return "无效值";}
}console.log(getMovementDirection(5)); // 输出: "向前"
console.log(getMovementDirection(-3)); // 输出: "向后"
console.log(getMovementDirection(0)); // 输出: "静止"

注意事项

  • 这些方法都是 ES6 新增的
  • Math.sign() 返回数字的符号:1, -1, 0, -0 或 NaN
  • Math.trunc() 简单地删除小数部分,而不是舍入
  • Math.fround() 在处理 WebGL 或需要 32 位浮点数时很有用

9. Math 常量 - 数学常数

使用场景:当你需要使用数学常数进行计算时。

示例代码

// 圆周率
console.log(Math.PI); // 输出: 3.141592653589793
// 计算圆的面积
const radius = 5;
const area = Math.PI * radius * radius;
console.log(area); // 输出: 78.53981633974483// 自然对数的底(欧拉数)
console.log(Math.E); // 输出: 2.718281828459045
// 连续复利公式
const principal = 1000;
const rate = 0.1;
const years = 5;
const amount = principal * Math.pow(Math.E, rate * years);
console.log(amount); // 输出: 1648.7212707001282// 2的平方根
console.log(Math.SQRT2); // 输出: 1.4142135623730951
// 2的倒数平方根
console.log(Math.SQRT1_2); // 输出: 0.7071067811865476
// 10的自然对数
console.log(Math.LN10); // 输出: 2.302585092994046
// 2的自然对数
console.log(Math.LN2); // 输出: 0.6931471805599453
// 以10为底e的对数
console.log(Math.LOG10E); // 输出: 0.4342944819032518
// 以2为底e的对数
console.log(Math.LOG2E); // 输出: 1.4426950408889634

注意事项

  • 这些常量是只读的,不能被修改
  • 它们提供了比手动输入更精确的数学常数
  • 在数学计算和科学应用中经常使用

10. 复杂数学计算 - 组合应用

使用场景:当你需要进行复杂的数学计算时。

示例代码

// 计算距离(两点之间的欧几里得距离)
function distance(x1, y1, x2, y2) {return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}console.log(distance(0, 0, 3, 4)); // 输出: 5// 角度转换
function degreesToRadians(degrees) {return (degrees * Math.PI) / 180;
}function radiansToDegrees(radians) {return (radians * 180) / Math.PI;
}console.log(degreesToRadians(90)); // 输出: 1.5707963267948966
console.log(radiansToDegrees(Math.PI / 4)); // 输出: 45// 生成指定范围内的随机整数数组(不重复)
function generateUniqueRandomNumbers(min, max, count) {if (max - min + 1 < count) {throw new Error("范围太小,无法生成不重复的随机数");}const result = new Set();while (result.size < count) {const randomNum = Math.floor(Math.random() * (max - min + 1)) + min;result.add(randomNum);}return Array.from(result);
}console.log(generateUniqueRandomNumbers(1, 20, 5)); // 输出: 如 [3, 7, 12, 15, 18]// 贝塞尔曲线的点(二次贝塞尔曲线)
function quadraticBezierPoint(p0, p1, p2, t) {const x =Math.pow(1 - t, 2) * p0.x + 2 * (1 - t) * t * p1.x + Math.pow(t, 2) * p2.x;const y =Math.pow(1 - t, 2) * p0.y + 2 * (1 - t) * t * p1.y + Math.pow(t, 2) * p2.y;return { x, y };
}const start = { x: 0, y: 0 };
const control = { x: 50, y: 100 };
const end = { x: 100, y: 0 };
console.log(quadraticBezierPoint(start, control, end, 0.5)); // 输出: { x: 50, y: 50 }

注意事项

  • 复杂计算通常需要组合多个 Math 方法
  • 浮点数运算可能存在精度问题,需要小心处理
  • 某些复杂的数学运算可能需要使用外部库
  • 性能敏感场景下,可以考虑对频繁使用的数学函数进行优化

Promise 异步处理

1. Promise.all() - 并行处理多个异步操作

使用场景:当你需要等待多个异步操作全部完成时。

示例代码

// 模拟一些异步请求
function fetchUserData() {return new Promise((resolve) => {setTimeout(() => resolve({ name: "张三", age: 25 }), 1000);});
}function fetchUserPosts() {return new Promise((resolve) => {setTimeout(() => resolve(["帖子1", "帖子2", "帖子3"]), 1500);});
}// 同时获取用户数据和帖子
Promise.all([fetchUserData(), fetchUserPosts()]).then(([userData, posts]) => {console.log("用户数据:", userData);console.log("用户帖子:", posts);}).catch((error) => {console.error("一个或多个请求失败:", error);});

注意事项

  • 如果任何一个 Promise 失败,Promise.all() 就会立即失败
  • 所有 Promise 都成功后,返回的结果是按照输入顺序排列的数组
  • 如果数组为空,Promise.all 会立即完成

2. Promise.race() - 竞态处理

使用场景:当你只关心多个异步操作中最先完成的一个时。

示例代码

// 带超时的请求
function fetchData() {return new Promise((resolve) => {setTimeout(() => resolve("数据获取成功"), 2000);});
}function timeout(ms) {return new Promise((_, reject) => {setTimeout(() => reject(new Error("请求超时")), ms);});
}// 如果请求时间超过1.5秒,就会超时
Promise.race([fetchData(), timeout(1500)]).then((result) => {console.log(result);}).catch((error) => {console.error(error.message); // 输出: 请求超时});

注意事项

  • Promise.race() 返回的是第一个完成的 Promise 的结果,无论成功或失败
  • 如果数组为空,Promise.race 会永远处于 pending 状态
  • 常用于实现超时处理或选择最快的资源

3. async/await - 更简洁的异步处理

使用场景:当你想以同步的方式编写异步代码时。

示例代码

// 模拟异步API调用
function fetchUser(id) {return new Promise((resolve) => {setTimeout(() => {resolve({ id, name: `用户${id}`, age: 20 + id });}, 1000);});
}// 使用async/await处理异步操作
async function getUserInfo(id) {try {console.log("开始获取用户信息...");const user = await fetchUser(id);console.log("用户数据:", user);// 可以使用条件判断if (user.age > 25) {console.log("这是一位成年人");}return user;} catch (error) {console.error("获取用户信息失败:", error);}
}// 调用异步函数
getUserInfo(5).then((userData) => {console.log("处理完成,最终用户数据:", userData);
});

注意事项

  • async 函数总是返回一个 Promise
  • await 关键字只能在 async 函数内部使用
  • 使用 try/catch 来捕获异步操作中的错误
  • 如果有多个独立的异步操作需要并行执行,可以结合 Promise.all 使用

4. Promise.allSettled() - 处理多个异步结果

使用场景:当你需要等待多个异步操作完成,并且不希望某个操作的失败影响其他操作时。

示例代码

// 定义三个Promise,一个成功,两个失败
const promise1 = Promise.resolve(42);
const promise2 = Promise.reject(new Error("请求失败"));
const promise3 = new Promise((resolve) =>setTimeout(() => resolve("迟到的数据"), 1000)
);Promise.allSettled([promise1, promise2, promise3]).then((results) => {console.log(results);// 输出:// [//   { status: "fulfilled", value: 42 },//   { status: "rejected", reason: Error: 请求失败 },//   { status: "fulfilled", value: "迟到的数据" }// ]// 过滤出成功的结果const successfulResults = results.filter((result) => result.status === "fulfilled").map((result) => result.value);console.log("成功的结果:", successfulResults);// 输出: [42, "迟到的数据"]// 检查哪些操作失败了results.forEach((result, index) => {if (result.status === "rejected") {console.log(`操作 ${index + 1} 失败: ${result.reason}`);}});
});

图解

image-20250427165201687

注意事项

  • ES2020 新增方法
  • 无论 Promise 是成功还是失败,Promise.allSettled() 都会等待所有 Promise 完成
  • 返回的结果数组包含每个 Promise 的状态和值/原因
  • 适用于需要执行多个独立操作并收集所有结果的场景

5. Promise.any() - 获取第一个成功结果

使用场景:当你只需要获取多个异步操作中第一个成功的结果时。

示例代码

// 从多个服务器加载数据,只需要第一个成功响应
function fetchFromServer1() {return new Promise((resolve, reject) => {setTimeout(() => reject(new Error("服务器1失败")), 1000);});
}function fetchFromServer2() {return new Promise((resolve) => {setTimeout(() => resolve("服务器2的数据"), 1500);});
}function fetchFromServer3() {return new Promise((resolve) => {setTimeout(() => resolve("服务器3的数据"), 800);});
}Promise.any([fetchFromServer1(), fetchFromServer2(), fetchFromServer3()]).then((firstSuccess) => {console.log("第一个成功的结果:", firstSuccess); // 输出: 服务器3的数据}).catch((error) => {console.log("所有请求都失败了");console.log(error); // 这是一个 AggregateError 对象});// 所有 Promise 都失败的情况
Promise.any([Promise.reject(new Error("失败1")),Promise.reject(new Error("失败2")),Promise.reject(new Error("失败3")),
]).catch((error) => {console.log(error instanceof AggregateError); // 输出: trueconsole.log(error.message); // 输出: All promises were rejectedconsole.log(error.errors); // 输出: [Error: 失败1, Error: 失败2, Error: 失败3]
});

注意事项

  • ES2021 新增方法
  • 和 Promise.race() 不同,Promise.any() 会忽略失败的 Promise,只关注成功的
  • 当所有 Promise 都失败时,会抛出 AggregateError (一个包含所有失败原因的错误)
  • 适用于从多个冗余资源中加载数据的场景

6. Promise.resolve() 和 Promise.reject() - 创建已决议的 Promise

使用场景:当你需要快速创建一个已完成或已拒绝的 Promise 时。

示例代码

// 创建一个立即完成的 Promise
const resolvedPromise = Promise.resolve("已完成");
resolvedPromise.then((value) => {console.log(value); // 输出: 已完成
});// 创建一个立即拒绝的 Promise
const rejectedPromise = Promise.reject(new Error("出错了"));
rejectedPromise.catch((error) => {console.error(error.message); // 输出: 出错了
});// 将同步函数包装为异步函数
function getValueAsync(value) {return Promise.resolve(value);
}// 根据条件返回成功或失败的 Promise
function fetchData(shouldSucceed) {return shouldSucceed? Promise.resolve({ data: "请求成功" }): Promise.reject(new Error("请求失败"));
}fetchData(true).then((result) => console.log(result)).catch((error) => console.error(error.message));// 处理 thenable 对象
const thenable = {then(resolve, reject) {resolve("来自 thenable 的数据");},
};Promise.resolve(thenable).then((value) => {console.log(value); // 输出: 来自 thenable 的数据
});

注意事项

  • Promise.resolve() 将值包装成一个已完成的 Promise
  • Promise.reject() 创建一个已拒绝的 Promise
  • 如果传给 Promise.resolve() 的是一个 Promise,它会原样返回
  • 如果传给 Promise.resolve() 的是一个 thenable 对象(带 then 方法的对象),它会被转换为 Promise

7. Promise 链式调用 - 连续处理异步操作

使用场景:当你需要按顺序执行一系列依赖前一步结果的异步操作时。

示例代码

// 模拟获取用户,然后获取用户的帖子,然后获取帖子的评论
function fetchUser(userId) {return new Promise((resolve) => {setTimeout(() => {resolve({ id: userId, name: "用户" + userId });}, 500);});
}function fetchPosts(user) {return new Promise((resolve) => {setTimeout(() => {resolve({user: user,posts: [{ id: 1, title: "第一篇帖子" },{ id: 2, title: "第二篇帖子" },],});}, 500);});
}function fetchComments(post) {return new Promise((resolve) => {setTimeout(() => {resolve({post: post,comments: [{ id: 1, text: "很棒的文章!" },{ id: 2, text: "谢谢分享!" },],});}, 500);});
}// 链式调用
fetchUser(1).then((user) => {console.log("用户:", user);return fetchPosts(user);}).then((result) => {console.log("帖子:", result.posts);return fetchComments(result.posts[0]);}).then((result) => {console.log("评论:", result.comments);}).catch((error) => {console.error("错误:", error);});// 同样的逻辑用 async/await 表达:
async function fetchUserPostsAndComments(userId) {try {const user = await fetchUser(userId);console.log("用户:", user);const postsResult = await fetchPosts(user);console.log("帖子:", postsResult.posts);const commentsResult = await fetchComments(postsResult.posts[0]);console.log("评论:", commentsResult.comments);return commentsResult;} catch (error) {console.error("错误:", error);}
}fetchUserPostsAndComments(1);

注意事项

  • 链式调用中的每个 .then() 都可以返回一个新的 Promise,形成连续的异步操作
  • 同一链中的错误处理可以由一个 .catch() 统一处理
  • 链式调用代码可能变得冗长,此时 async/await 通常更易读
  • 在每个 .then() 中返回值很重要,否则下一个 .then() 将收到 undefined

8. Promise 并发控制 - 限制并发请求数量

使用场景:当你需要处理大量异步任务,但想限制同时执行的任务数量时。

示例代码

// 模拟异步请求
function fetchData(id) {return new Promise((resolve) => {const delay = Math.floor(Math.random() * 1000) + 500;console.log(`开始请求 ${id},预计 ${delay}ms`);setTimeout(() => {console.log(`请求 ${id} 完成`);resolve(`数据 ${id}`);}, delay);});
}// 并发控制函数
async function concurrentPromises(tasks, maxConcurrent) {const results = [];const executing = new Set();for (const [index, task] of tasks.entries()) {const promise = Promise.resolve().then(() => task());results[index] = promise;// 如果达到最大并发数,等待某个任务完成if (maxConcurrent <= executing.size) {await Promise.race(executing);}// 将当前任务添加到执行集合,并在完成后移除executing.add(promise);promise.then(() => executing.delete(promise));}return Promise.all(results);
}// 准备任务
const tasks = Array.from({ length: 10 }, (_, i) => {return () => fetchData(i + 1);
});// 执行任务,最多同时执行3个
concurrentPromises(tasks, 3).then((results) => {console.log("所有请求完成");console.log(results);
});// 使用队列实现并发控制(另一种方法)
async function requestWithConcurrencyLimit(urls, limit) {const results = [];const queue = [...urls];const executing = [];while (queue.length > 0) {// 从队列中取出下一个URLconst url = queue.shift();// 创建请求Promise并将其包装,以便在完成时从executing数组中移除const p = fetchData(url).then((result) => {executing.splice(executing.indexOf(p), 1);return result;});// 跟踪正在执行的Promiseresults.push(p);executing.push(p);// 如果达到限制,等待一个Promise完成if (executing.length >= limit) {await Promise.race(executing);}}// 等待所有结果return Promise.all(results);
}

注意事项

  • 控制并发对于防止请求过载和资源竞争很重要
  • Set 用于跟踪正在执行的 Promise,方便移除完成的任务
  • 使用 Promise.race() 来等待任意一个任务完成
  • 实际应用中可能需要处理错误和重试逻辑

9. async 迭代器 - 异步遍历数据

使用场景:当你需要异步迭代大量数据或流时。

示例代码

// 模拟异步数据源
async function* generateData() {for (let i = 1; i <= 5; i++) {// 模拟异步操作await new Promise((resolve) => setTimeout(resolve, 500));yield `数据项 ${i}`;}
}// 使用 for await...of 遍历异步迭代器
async function processData() {console.log("开始处理数据...");for await (const item of generateData()) {console.log("收到:", item);}console.log("数据处理完成");
}processData();// 异步迭代数据库结果
async function* fetchUsers(batchSize = 2) {// 模拟数据库中的用户const allUsers = [{ id: 1, name: "张三" },{ id: 2, name: "李四" },{ id: 3, name: "王五" },{ id: 4, name: "赵六" },{ id: 5, name: "钱七" },];// 批量获取用户for (let i = 0; i < allUsers.length; i += batchSize) {// 模拟数据库查询延迟await new Promise((resolve) => setTimeout(resolve, 1000));const batch = allUsers.slice(i, i + batchSize);console.log(`获取用户批次: ${i / batchSize + 1}`);yield batch;}
}// 处理用户数据
async function processAllUsers() {let userCount = 0;for await (const userBatch of fetchUsers()) {console.log("处理用户批次:", userBatch);userCount += userBatch.length;}console.log(`总共处理了 ${userCount} 个用户`);
}processAllUsers();

注意事项

  • 异步迭代器是 ES2018 的特性
  • 使用 async function* 定义异步生成器函数
  • 使用 for await…of 循环迭代异步生成的值
  • 适用于处理流式数据、分页 API 结果等场景

10. 错误处理和调试 - 处理 Promise 中的错误

使用场景:当你需要在 Promise 链中优雅地处理错误和进行调试时。

示例代码

// 一个可能出错的异步函数
function riskyOperation(shouldFail = false) {return new Promise((resolve, reject) => {setTimeout(() => {if (shouldFail) {reject(new Error("操作失败"));} else {resolve("操作成功");}}, 500);});
}// 1. 捕获和处理错误
riskyOperation(true).then((result) => {console.log(result);}).catch((error) => {console.error("捕获到错误:", error.message);// 可以返回一个默认值继续链return "默认结果";}).then((result) => {console.log("继续处理:", result);});// 2. 不同级别的错误处理
function operation1() {return riskyOperation(false);
}function operation2() {return riskyOperation(true);
}function operation3() {return riskyOperation(false);
}operation1().then((result) => {console.log("操作1成功:", result);return operation2();}).catch((error) => {console.error("操作2失败:", error.message);// 可以继续执行操作3return operation3();}).then((result) => {console.log("最终结果:", result);}).catch((error) => {console.error("致命错误:", error.message);}).finally(() => {console.log("清理资源...");});// 3. async/await 中的错误处理
async function performOperations() {try {const result1 = await operation1();console.log("操作1成功:", result1);try {const result2 = await operation2();console.log("操作2成功:", result2);} catch (error) {console.error("操作2失败,但继续执行:", error.message);}const result3 = await operation3();console.log("操作3成功:", result3);return "所有操作完成";} catch (error) {console.error("操作失败:", error.message);return "操作链中断";} finally {console.log("清理资源...");}
}performOperations().then(console.log);// 4. 未捕获的 Promise 错误
window.addEventListener("unhandledrejection", (event) => {console.warn("未处理的 Promise 拒绝:", event.promise, event.reason);// 可以阻止默认处理event.preventDefault();
});// 故意不处理错误
Promise.reject(new Error("我没有被处理"));

注意事项

  • 始终在 Promise 链的末尾添加 .catch() 处理错误
  • .finally() 用于无论 Promise 成功或失败都需要执行的清理代码
  • 不同级别的 try/catch 可以进行细粒度的错误处理
  • 使用 unhandledrejection 事件可以捕获全局未处理的 Promise 拒绝
  • 调试时可以使用 console.log 或断点来跟踪 Promise 执行流程

总结

JavaScript 内置对象的方法为我们提供了丰富的工具,帮助我们更高效地处理各种编程任务。灵活运用这些方法可以让代码更简洁、更易读,也能提高开发效率。

希望这篇文章能帮助你更好地理解和使用这些常用方法。在实际编程中,建议查阅MDN Web 文档获取更详细的信息和最新的 API 变化。

祝你编程愉快!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/78413.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OceanBase TPCC测试常见报错汇总

OceanBase TPCC测试常见报错汇总 报错1:加载测试数据时创建tablegroup失败报错2:加载测试数据时执行超时报错3:加载测试数据时funcs.sh函数找不到报错4:加载数据时报错超过租户内存上限办法一:增加租户内存办法二:调高转储线程数办法三:调整MemStore内存占比和冻结触发阈…

Flutter 在 Dart 3.8 开始支持 Null-Aware Elements 语法,自动识别集合里的空元素

近日&#xff0c;在 Dart 3.8 的 changelog 里正式提交了 Null-Aware Elements 语法&#xff0c;该语法糖可以用于在 List、Set、Map 等集合中处理可能为 null 的元素或键值对&#xff0c;简化显式检查 null 的场景&#xff1a; /之前 var listWithoutNullAwareElements [if …

SAIL-RK3588协作机器人运动控制器技术方案

一、核心能力与政策适配‌ ‌政策合规性‌ 满足工信部《智能机器人重点技术攻关指南》要求&#xff0c;支持 ‌EtherCAT主站协议&#xff08;符合IEC 61158标准&#xff09;‌&#xff0c;助力企业申报工业机器人研发专项补贴&#xff08;最高300万元/项目&#xff09;‌核心板…

Eigen几何变换类 (Transform, Quaternion等)

1. Transform 类&#xff1a;仿射/射影变换 模板参数 cpp Transform<Scalar, Dim, Mode, Options> Scalar&#xff1a;数据类型&#xff08;如 float, double&#xff09;。 Dim&#xff1a;维度&#xff08;2 或 3&#xff09;。 Mode&#xff1a;变换类型&#xf…

openGauss手工配置主备

1、初始化 创建一个操作系统用户&#xff0c;例如postgres&#xff0c;为这个用户设置PATH和LD_LIBRARY_PATH环境变量&#xff0c;指向opengauss/bin和opengauss/lib export GAUSSHOME/mnt/disk01/opengauss export PATH$GAUSSHOME/bin:$PATH export LD_LIBRARY_PATH$GAUSS…

CSS预处理器对比:Sass、Less与Stylus如何选择

引言 CSS预处理器已成为现代前端开发的标准工具&#xff0c;它们通过添加编程特性来增强纯CSS的功能&#xff0c;使样式表更加模块化、可维护且高效。在众多预处理器中&#xff0c;Sass、Less和Stylus是三个最流行的选择&#xff0c;它们各自拥有独特的语法和功能特点。本文将深…

基于Docker、Kubernetes和Jenkins的百节点部署架构图及信息流描述

以下是基于Docker、Kubernetes和Jenkins的百节点部署架构图及信息流描述,使用文本和Mermaid语法表示: 架构图(Mermaid语法) #mermaid-svg-WWCAqL1oWjvRywVJ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-WWCAq…

js中get,set用法

1、作为对象的访问器属性 //使用Object.definePropertylet obj {_a:123};Object.defineProperty(obj, "a", {get() {return this._a;},set(val) {this._aval},});console.log(obj.a); //123obj.a456console.log(obj.a) // 456 //使用对象字面量let obj {_a:123,ge…

Steam游戏服务器攻防全景解读——如何构建游戏级抗DDoS防御体系?

Steam游戏服务器的DDoS攻防体系设计&#xff0c;从协议层漏洞利用到业务连续性保障&#xff0c;深度拆解反射型攻击、TCP状态耗尽等7类威胁场景。基于全球15个游戏厂商攻防实战数据&#xff0c;提供包含边缘节点调度、AI流量指纹识别、SteamCMD加固配置的三维防护方案&#xff…

【AI】SpringAI 第四弹:接入本地大模型 Ollama

Ollama 是一个开源的大型语言模型服务工具。它的主要作用是帮助用户快速在本地运行大模型&#xff0c; 简化了在 Docker 容器内部署和管理大语言模型&#xff08;LLM&#xff09;的过程。 1. 确保Ollama 已经启动 # 查看帮助文档 ollama -h# 自动下载并启动 ollama run deeps…

大语言模型的评估指标

目录 一、混淆矩阵 1. 混淆矩阵的结构&#xff08;二分类为例&#xff09; 2.从混淆矩阵衍生的核心指标 3.多分类任务的扩展 4. 混淆矩阵的实战应用 二、分类任务核心指标 1. Accuracy&#xff08;准确率&#xff09; 2. Precision&#xff08;精确率&#xff09; 3. …

SpringBoot Gradle插件:构建与打包配置

文章目录 引言一、Spring Boot Gradle插件基础二、依赖管理与配置三、应用打包配置四、启动脚本与运行配置五、多环境构建与配置六、集成Docker与云原生支持七、实践案例&#xff1a;自定义Spring Boot应用构建总结 引言 在Java生态系统中&#xff0c;Gradle作为一种灵活且强大…

Vue3 组件通信与插槽

Vue3 组件通信方式全解&#xff08;10种方案&#xff09; 一、组件通信方式概览 通信方式适用场景数据流向复杂度Props/自定义事件父子组件简单通信父 ↔ 子⭐v-model 双向绑定父子表单组件父 ↔ 子⭐⭐Provide/Inject跨层级组件通信祖先 → 后代⭐⭐事件总线任意组件间通信任…

【KWDB 创作者计划】_嵌入式硬件篇---数字电子器件

文章目录 前言一、系列前缀(如 "74" 或 "54")74(商用级)54(工业级)二、逻辑家族(如 "LS"、"HC"、"HCT" 等)TTL(晶体管-晶体管逻辑)家族CMOS(互补金属氧化物半导体)家族BiCMOS(双极 CMOS)家族三、功能编号(如…

黄勇的《架构探险:从Java到大数据》内容详解

《架构探险&#xff1a;从Java到大数据》内容详解 1. 书籍核心主题 黄勇的《架构探险&#xff1a;从Java到大数据》是一本系统性探讨架构设计演进的著作&#xff0c;结合Java技术栈和大数据场景&#xff0c;深入分析了从单体架构到分布式、微服务、云原生的演进路径&#xff0…

【动手学强化学习】番外8-IPPO应用框架学习与复现

文章目录 一、待解决问题1.1 问题描述1.2 解决方法 二、方法详述2.1 必要说明&#xff08;1&#xff09;MAPPO 与 IPPO 算法的区别在于什么地方&#xff1f;&#xff08;2&#xff09;IPPO 算法应用框架主要参考来源 2.2 应用步骤2.2.1 搭建基础环境2.2.2 IPPO 算法实例复现&am…

驱动开发硬核特训 · Day 17:深入掌握中断机制与驱动开发中的应用实战

&#x1f3a5; 视频教程请关注 B 站&#xff1a;“嵌入式 Jerry” 一、前言 在嵌入式驱动开发中&#xff0c;“中断”几乎无处不在。无论是 GPIO 按键、串口通信、网络设备&#xff0c;还是 SoC 上的各种控制器&#xff0c;中断都扮演着核心触发机制的角色。对中断机制掌握程度…

通过门店销售明细表用PySpark得到每月每个门店的销冠和按月的同比环比数据

假设我在Amazon S3上有销售表的Parquet数据文件的路径&#xff0c;包含ID主键、门店ID、日期、销售员姓名和销售额&#xff0c;需要分别用PySpark的SparkSQL和Dataframe API统计出每个月所有门店和各门店销售额最高的人&#xff0c;不一定是一个人&#xff0c;以及他所在的门店…

PostgreSQL 常用日志

PostgreSQL 常用日志详解 PostgreSQL 提供了多种日志类型&#xff0c;用于监控数据库活动、排查问题和优化性能。以下是 PostgreSQL 中最常用的日志类型及其配置和使用方法。 一、主要日志类型 日志类型文件位置主要内容用途服务器日志postgresql-<日期>.log服务器运行…

MySQL 存储过程:解锁数据库编程的高效密码

目录 一、什么是存储过程?二、创建存储过程示例 1:创建一个简单的存储过程示例 2:创建带输入参数的存储过程示例 3:创建带输出参数的存储过程三、调用存储过程调用无参数存储过程调用带输入参数的存储过程调用带输出参数的存储过程四、存储过程中的流控制语句示例 1:使用 …