\
Destructuring Objects and Arrays
const book = {
id: 1,
title: "The Lord of the Rings",
publicationDate: "1954-07-29",
author: "J. R. R. Tolkien",
genres: [
"fantasy",
"high-fantasy",
"adventure",
"fiction",
"novels",
"literature",
],
hasMovieAdaptation: true,
pages: 1216,
translations: {
spanish: "El señor de los anillos",
chinese: "魔戒",
french: "Le Seigneur des anneaux",
},
reviews: {
goodreads: {
rating: 4.52,
ratingsCount: 630994,
reviewsCount: 13417,
},
librarything: {
rating: 4.53,
ratingsCount: 47166,
reviewsCount: 452,
},
},
};
可以直接取用物件中的key,得到相對應value
const { title, author, pages, pulicationDate, genres, hasMovieAdaptation} = book;
console.log(title) // => The Lord of the Rings
可以直接將陣列解構復值
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(rest); // [30, 40, 50];
「…」語法,可用在物件或陣列上
可以將陣列的值複製進另一個陣列
const updateBook = {
...book,
moviePublicationDate: "2001-12-19",
pages: 1210,
};
//這樣updateBook將會包含book物件的所有屬性,又加上後面兩個屬性
模板語法
用重音符將${} 包起來,${}中可以放語法
const summary = `${title} is a book`;
console.log(summary) // 'The Lord of the Ring is a book;'
三元運算符
如果第一個邏輯結果為 True
,返回 ? 後第一個結果,否則返回第二個
const isBookAvaliable = false;
const canTheBookBeBorrowed = isBookAvaliable ? 'Avaliable' : 'Unavaliable';
? (可選鏈運算子) 及 ?? (null合併運算子)
const librarything = book.reviews.librarything?.reviewsCount ?? 0;
**?**
表示如果**book.reviews.librarything**
是**null**
或**undefined**
,則不會試圖訪問**reviewsCount**
属性,而是直接返回**undefined**
**?? 0**
:表示如果左側的表達式(**book.reviews.librarything?.reviewsCount**
)的結果是**null**
或**undefined**
,則**librarything**
的值將是**0**
。
|| 邏輯運算子 與 ?? 的區別
**??
**是會在左側為 **null**
或 **undefined**
時返回右側的值
**||**
則會在左側為任何 falsy (包含 0、false、null、undefined 和 “”) 的值時返回右邊的值
let count = 0;
console.log(count ?? 10); // 輸出 0,因為 count 不是 null 或 undefined
console.log(count || 10); // 輸出 10,因為 count 是 falsy 值
陣列 .map() 方法
用於將陣列中的每個元素按照某種計算規則轉換成新的元素,然後將這些新元素組成一個新陣列返回
const x = [1,2,3,4,5];
console.log(x.map((el)=> el*2); // [2,4,6,8,10]
陣列 .filter() 方法
根據特定條件從一個陣列中創建一個新陣列,新陣列只包含符合條件的元素
let newArray = array.filter(function(item, index, arr), thisArg);
const longBooks = books.filter(book => book.pages > 500);
console.log(longBooks);
// longBooks 將會只包含那些超過 500 頁的書
陣列 .reduce() 方法
將陣列中的所有元素累計成單一的結果。**reduce()**
對陣列中的每個元素(從左到右)執行一個由你提供的 reducer 函數,並將其結果累積起來,最終返回一個單一的值
**reduce()**
方法接受兩個參數:一個 reducer 函數和一個可選的初始累加值。
array.reduce(function(accumulator, currentValue, currentIndex, array), initialValue)
- accumulator:累加器累積回調的返回值;它是上一次調用回調後返回的累積值,或者是提供的初始值(
**initialValue**
)。 - currentValue:陣列中正在處理的當前元素。
- currentIndex(可選):陣列中正在處理的當前元素的索引。如果提供了
**initialValue**
,則索引號從**0**
開始,否則從**1**
開始。 - array(可選):調用
**reduce**
的陣列。 - initialValue(可選):作為第一個調用
**reduce**
函數時第一個參數的值。
如果不提供 **initialValue**
,**reduce()**
會將數組的第一個元素作為初始累加值,並從第二個元素開始執行 reducer 函數。如果陣列為空且沒有提供 **initialValue**
,將拋出一個錯誤。
範例:
const pagesAllBooks = books.reduce((acc, book)=>acc + book.pages,0);
陣列 .filter() 方法
排序陣列中的元素
const arr = [3,6,1,7,9]
const sorted = arr.sort((a,b)=> a-b); // [1,3,6,7,9] 升冪
const down = arr.sort((a,b) => b-a); // [9,7,6,3,1] 降冪
- compareFunction(可選):一個可以自定義如何排序元素的函數。這個函數應該接受兩個參數(通常表示為 a 和 b),並根據比較的需要返回一個數值:
- 如果返回值小於 0,那麼 a 會被排在 b 前面。
- 如果返回值等於 0,a 和 b 的相對位置不變。
- 如果返回值大於 0,b 會被排在 a 前面。
- 因為
**sort()**
方法對原陣列進行原地排序,使用時要注意可能會改變原始數據。
新增元素到陣列
const newBook = {
id: 6,
title:"Harry Potter and the Chamber of Secrets",
author: "J. K. Rowling",
}
const booksAfterAdding = [...books, newBook];
console.log(booksAfterAdding);
刪除陣列元素
const booksAfterDelete = books.filter(book => book.id !== 3);
console.log(books); //結果將不含 id 為 3 的書
非同步
Promise
什麼是 Promise?
**Promise**
是一個對象,代表了一個最終可能完成或失敗的非同步操作的結果。它允許你對非同步操作的成功值或失敗原因進行關聯處理。
Promise 的狀態
**Promise**
有三種狀態:
- Pending(待定):初始狀態,非同步操作尚未完成也未被拒絕。
- Fulfilled(已實現):表示相關的非同步操作已成功完成。
- Rejected(已拒絕):表示相關的非同步操作已失敗。
創建 Promise
你可以使用 **Promise**
的構造函數來創建一個新的 **Promise**
。構造函數接受一個執行器函數作為參數,這個函數又接受兩個函數作為參數:**resolve**
和 **reject**
。
let myPromise = new Promise((resolve, reject) => {
// 非同步操作
const condition = true; // 假設條件判斷為非同步操作是否成功
if (condition) {
resolve('Operation successful');
} else {
reject('Error occurred');
}
});
使用 Promise
當 **Promise**
被解決或拒絕時,你可以使用 **.then()**
和 **.catch()**
方法來處理成功或失敗的結果。
**.then()**
:接受兩個函數作為參數。第一個函數是在**Promise**
被解決時調用的,第二個(可選)函數是在**Promise**
被拒絕時調用的。**.catch()**
:接受一個函數作為參數,用於處理**Promise**
被拒絕的情況。
fetch("<http://jsonplaceholder.typicode.com/todos>")
.then((res)=>res.json())
.then(data => console.log(data
Async & Await 語法糖
在 JavaScript 中,**await**
是一個用於處理非同步操作的關鍵字,它只能在 **async**
函數內部使用。**await**
關鍵字可以暫停 **async**
函數的執行,等待 **Promise**
的解決或拒絕,然後恢復 **async**
函數的執行並返回解決值。
基本使用
要使用 **await**
,首先需要定義一個 **async**
函數。**async**
函數是一種返回 **Promise**
對象的函數。在這個函數體內,你可以使用 **await**
來等待 **Promise**
完成。
async function getTodos() {
const res = await fetch("<http://jsonplaceholder.typicode.com/todos>");
const data = await res.json();
console.log(data);
}
在上述代碼中,**somePromise()**
應該是一個返回 **Promise**
的函數。當 **Promise**
被解決時,它的解決值會被賦值給 **result**
變量。如果 **Promise**
被拒絕,則會拋出異常,可以使用 **try...catch**
結構來捕獲這個異常。
詳細解釋
當 **await**
表達式被執行時,它會暫停包含它的 **async**
函數的執行。如果 **Promise**
成功解決,則返回的值會作為 **await**
表達式的結果。如果 **Promise**
被拒絕,則拒絕的原因會被拋出作為異常。
**await**
只能在**async**
函數內部使用。- 使用
**await**
時,如果不加控制,可能會導致程序的性能下降,因為它會在等待**Promise**
解決時暫停函數的執行。在處理多個獨立的**Promise**
時,應考慮並行執行它們(如使用**Promise.all()**
)。 **await**
會將非**Promise**
值轉換為立即解決的**Promise**
,這意味著你可以等待任何值,但這可能會導致不必要的微小延遲。