ES6必會重點彙總

CodeForBetter發表於2023-04-28

當下的前端開發已經成為一項非常流行的技能。在這個領域中,ES6是一個重要的主題。ES6是ECMAScript 2015的縮寫,是JavaScript語言的下一個版本,引入了很多新的語言特性和API,讓JavaScript更加強大和易用。

本文將介紹ES6中的一些重點內容,幫助你瞭解ES6的新特性並更好地掌握JavaScript語言。

1. 塊級作用域

在ES6之前,JavaScript只有全域性作用域和函式作用域。這意味著在函式中宣告的變數只能在該函式內部使用,而在全域性作用域中宣告的變數則可以在任何地方使用。這種作用域機制往往會導致變數命名衝突和程式碼不可維護。

ES6中引入了塊級作用域,可以透過使用letconst關鍵字來宣告塊級變數。塊級變數只在當前塊中有效,不會汙染全域性作用域。

function test() {
  if (true) {
    let a = 1;
    const b = 2;
  }
  console.log(a); // ReferenceError: a is not defined
  console.log(b); // ReferenceError: b is not defined
}

在上面的程式碼中,變數ab只在if塊中有效,無法在函式外部訪問。這種塊級作用域機制可以有效地提高程式碼的可維護性。

2. 箭頭函式

ES6引入了箭頭函式,它提供了一種更簡潔的語法來定義函式。

箭頭函式的語法如下:

(param1, param2, …, paramN) => { statements }

例如,我們可以使用箭頭函式來計算一個陣列中所有元素的和:

let arr = [1, 2, 3, 4, 5];
let sum = arr.reduce((prev, curr) => prev + curr);
console.log(sum); // 15

上面的程式碼中,reduce方法使用箭頭函式來將陣列中所有元素相加,並返回最終的和。

與傳統的函式定義方式不同,箭頭函式沒有自己的thisarguments,它們的值是從外層作用域繼承而來的。

3. 模板字串

在ES6之前,我們通常使用字串拼接的方式來構建字串。這種方式不僅繁瑣,而且容易出錯。

ES6中引入了模板字串,它提供了一種更方便的方式來構建字串。

模板字串的語法如下:

`string text ${expression} string text`

其中,${expression}表示一個表示式,可以是變數、函式呼叫等。模板字串中的表示式會被計算,並將結果插入到字串中。例如:

let name = 'World';
console.log(`Hello, ${name}!`); // Hello, World!

上面的程式碼中,${name}會被計算並插入到字串中。

模板字串還支援多行字串的定義,可以避免使用\n來表示換行符。

let str = `
  This is a
  multi-line
  string.
`;
console.log(str); // This is a
                  // multi-line
                  // string.

4. 解構賦值

在JavaScript中,我們經常需要從物件或陣列中獲取一些資料並將它們分配給變數。傳統的方式是逐個取出每個屬性或元素並將它們賦值給變數。這種方式不僅繁瑣,而且容易出錯。

ES6中引入瞭解構賦值,可以讓我們更方便地從物件或陣列中獲取資料。

物件解構賦值

物件解構賦值的語法如下:

let {prop1, prop2} = obj;

其中,obj是一個物件,prop1prop2是物件的屬性。解構賦值會將obj.prop1的值分配給變數prop1,將obj.prop2的值分配給變數prop2

例如:

let obj = {name: 'Alice', age: 20};
let {name, age} = obj;
console.log(name); // Alice
console.log(age); // 20

陣列解構賦值

陣列解構賦值的語法如下:

let [elem1, elem2, ...rest] = arr;

其中,arr是一個陣列,elem1elem2是陣列的元素。解構賦值會將arr[0]的值分配給變數elem1,將arr[1]的值分配給變數elem2

例如:

let arr = [1, 2, 3, 4, 5];
let [first, second, ...rest] = arr;
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]

陣列解構還可以用於交換變數的值,如下所示:

let a = 1, b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1

在上面的例子中,[a, b] = [b, a]將變數ab的值交換。

5. 類和繼承

ES6中引入了類的概念,可以使用類來定義物件的屬性和方法。

類的語法如下:

class MyClass {
  constructor(prop1, prop2) {
    this.prop1 = prop1;
    this.prop2 = prop2;
  }

  method1() {
    // ...
  }

  method2() {
    // ...
  }
}

上面的程式碼中,MyClass是一個類,包含了一個建構函式和兩個方法。可以使用new關鍵字來建立一個MyClass類的例項。

ES6中還支援繼承,可以使用extends關鍵字來繼承一個類。

class MySubClass extends MyClass {
  constructor(prop1, prop2, prop3) {
    super(prop1, prop2);
    this.prop3 = prop3;
  }

  method3() {
    // ...
  }
}

上面的程式碼中,MySubClass是一個繼承自MyClass的子類,包含了一個建構函式和一個方法。可以使用new關鍵字來建立一個MySubClass類的例項。

6. Promise

ES6中引入了Promise物件,用於處理非同步操作。Promise可以將非同步操作轉換為同步操作,避免了回撥函式巢狀的問題。

Promise有三種狀態:pendingfulfilledrejected。當Promise處於pending狀態時,表示非同步操作尚未完成。當Promise處於fulfilled狀態時,表示非同步操作成功完成。當Promise處於rejected狀態時,表示非同步操作失敗。

Promise的語法如下:

let promise = new Promise((resolve, reject) => {
  // 非同步操作
  if (/* 非同步操作成功 */) {
    resolve(result);
  } else {
    reject(error);
  }
});

上面的程式碼中,promise是一個Promise物件,它包含了一個非同步操作和兩個回撥函式:resolvereject。如果非同步操作成功完成,則呼叫resolve函式並傳遞結果;如果非同步操作失敗,則呼叫reject函式並傳遞錯誤資訊。

可以使用thencatch方法來處理Promise物件的結果。then方法接收一個回撥函式,該函式在非同步操作成功完成時被呼叫,並接收非同步操作的結果作為引數。catch方法接收一個回撥函式,該函式在非同步操作失敗時被呼叫,並接收錯誤資訊作為引數。

例如:

let promise = new Promise((resolve, reject) => {
  // 非同步操作
  if (/* 非同步操作成功 */) {
    resolve(result);
  } else {
    reject(error);
  }
});

promise.then(result => {
  console.log(result);
}).catch(error => {
   console.error(error);
});

7. async/await

ES6 引入了 async/await,它使得非同步操作像同步操作一樣簡單易讀,使得程式碼的可讀性和可維護性都得到了極大的提升。

在 async/await 中,我們使用 async 關鍵字來宣告一個非同步函式,該函式返回一個 Promise 物件。await 關鍵字用於等待一個非同步函式執行完成,並返回該函式的執行結果。

下面是一個簡單的例子:

async function getData() {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  console.log(data);
}
getData();

在上面的例子中,我們定義了一個名為 getData 的非同步函式,該函式使用 await 等待一個 HTTP 請求完成,並解析 JSON 資料。最後,我們輸出解析後的資料到控制檯。
需要注意的是,在使用 async/await 時,我們需要把所有可能丟擲錯誤的程式碼用 try/catch 包裹起來,以便捕獲和處理錯誤。下面是一個使用 async/await 處理非同步請求和錯誤的例子:

async function getData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Error:', error);
  }
}

getData();

在上面的例子中,我們使用 try/catch 包裹所有非同步程式碼,以捕獲可能出現的錯誤。如果有錯誤丟擲,它們將被捕獲並在 catch 塊中處理。

8. 函式預設引數

ES6中引入了函式預設引數,用於簡化函式定義並避免傳遞undefined值的問題。

函式預設引數的語法如下:

function func(param1 = defaultValue1, param2 = defaultValue2, …, paramN = defaultValueN) {
  // ...
}

例如:

function greet(name = 'World') {
  console.log(`Hello, ${name}!`);
}
greet(); // Hello, World!
greet('John'); // Hello, John!

在上面的例子中,greet函式包含一個預設引數name,其預設值為'World'。如果呼叫函式時未傳遞引數,則使用預設值;如果傳遞了引數,則使用傳遞的值。

9. 函式剩餘引數

ES6中,剩餘引數(Rest Parameters)是一種特殊的引數形式,允許我們將不定數量的參數列示為一個陣列。

使用剩餘引數,可以在不知道函式引數個數的情況下,輕鬆地傳遞多個引數,這些引數會被自動匯聚為一個陣列。

剩餘引數的語法格式為三個點(...)後跟一個變數名,例如:

function(myParam, ...myOtherParams) {
    // Function code here
}

剩餘引數需要宣告在引數列表的最後一個引數位置上,並且一個函式只能有一個剩餘引數。剩餘引數被賦值為一個陣列,其中包含了函式呼叫時傳遞的所有剩餘引數。

以下是一個使用剩餘引數的案例:

function sum(base, ...args) {
    let total = base;
    for (const value of args) {
        total += value;
    }
    return total;
}

console.log(sum(10, 20, 30, 40)); // 輸出:100

在上面的例子中,我們定義了一個名為sum的函式,它接受一個必需引數base和一個剩餘引數args。

在函式內部,我們使用for...of迴圈遍歷剩餘引數args,並將它們依次加入到總和total中,最終返回total。當我們呼叫sum函式並傳入一些引數時,它會將這些引數匯聚為一個陣列args,並對陣列中的元素進行求和操作。

總之,剩餘引數是一種非常方便的特性,它允許我們輕鬆地處理不定數量的函式引數,並將它們作為一個陣列進行處理。

10. Map/Set

ES6中的Map和Set是JavaScript中新增的兩種集合型別。它們都可以儲存多個資料項,並提供了方便的方法進行元素的增刪改查。

Map

Map是一組鍵值對的集合,其中每個鍵唯一且可以是任意資料型別,值可以是任意資料型別。Map的常見用法包括儲存和查詢鍵值對、迭代鍵值對等。例如:

建立

const myMap = new Map();

新增、獲取、刪除元素

myMap.set('key1', 'value1'); // 新增元素
myMap.get('key1'); // 獲取元素
myMap.delete('key1'); // 刪除元素

遍歷

myMap.forEach((value, key) => {
  console.log(`${key} = ${value}`);
});

// 或者使用 for...of 迴圈也可以遍歷 Map
for (const [key, value] of myMap) {
  console.log(`${key} = ${value}`);
}


Map 轉換為陣列

可以使用 Array.from 方法將 Map 轉換為陣列:

const myMap = new Map();
myMap.set('key1', 'value1');
myMap.set('key2', 'value2');
const myArr = Array.from(myMap);
console.log(myArr); // [['key1','value1'], ['key2','value2']]


Set

Set是一組無序的、不重複的值的集合,其中每個值唯一且可以是任意資料型別。Set的常見用法包括儲存和查詢值、判斷值是否存在等。

建立

const mySet = new Set();

新增、獲取、刪除元素

mySet.add('value1'); // 新增元素
mySet.has('value1'); // 判斷是否存在
mySet.delete('value1'); // 刪除元素

遍歷

mySet.forEach(value => {
  console.log(value);
});
// 使用 for...of 迴圈也可以遍歷 Set:
for (const value of mySet) {
  console.log(value);
}



Set 轉換為陣列

可以使用 Array.from 方法將 Set 轉換為陣列:

const mySet = new Set(['value1', 'value2']);
const myArr = Array.from(mySet);
console.log(myArr); // ['value1', 'value2']

總的來說,Map和Set的使用非常類似,但是需要根據實際情況進行選擇。如果需要使用鍵值對來儲存資料,可以使用Map;如果僅需要儲存不重複的值,可以使用Set。

結論

ES6是一個重要的JavaScript版本,它引入了許多新特性,包括let和const關鍵字、模板字面量、箭頭函式、類和模組等。這些特性使得JavaScript更易於開發和維護,並提高了效能和可讀性。在日常開發中,我們應該儘可能地使用這些新特性來提高開發效率和程式碼質量。

相關文章