[程式] JavaScript ES6 筆記

紀錄 JS ES6 的相關語法筆記

Raellen
Raellen
[程式] JavaScript ES6 筆記

\

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**,這意味著你可以等待任何值,但這可能會導致不必要的微小延遲。