匯總 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.pswp.cn/pingmian/78413.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/78413.shtml
英文地址,請注明出處:http://en.pswp.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:使用 …