iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0
JavaScript

30天 JavaScript 提升計畫:從零到精通結合2024年的創新功能系列 第 7

第 7 天:ES6 新特性 - 擴展運算子與合併運算子

  • 分享至 

  • xImage
  •  

在 ES6 及其之後的規格中,擴展運算子和合併運算子簡化程式碼編寫,提高了程式碼的可讀性和維護性。
其實,學後端的這幾週發現 php 也有相同的運算子,使用方法和原理幾乎是一樣的,有點他鄉遇故知的感動!

擴展運算子 ...:用於展開數組或對象,在函數呼叫、數組合併、對象合併等場景中非常有用。
合併運算子 ??:用於處理 nullundefined 的情況,為變數提供預設值。

擴展運算子 ...


擴展運算子 ... 用於將 array 或 object 展開,應用於函數呼叫、數組構造和物件合併的地方,簡單來說,這個運算子不管是陣列還是物件都可以使用,有點像淺拷貝的原理!

陣列

  1. 函數呼叫:可以將陣列展開當作函數的參數帶入 -> 這個是學後端後發現前輩們很常用的手法!
    const numbers = [1, 2, 3];
    
    function sum(a, b, c) {
      return a + b + c;
    }
    
    console.log(sum(...numbers)); // 6
    
  2. 數字組合併:可以將多個數字組合併成一個新數組。
    const arr1 = [1, 2, 3];
    const arr2 = [4, 5, 6];
    
    const combined = [...arr1, ...arr2];
    
    console.log(combined);        // [1, 2, 3, 4, 5, 6]
    
  3. 數組複製:可以使用擴展運算子快速複製一個數組,避免記憶體互相影響。
    const original = [1, 2, 3];
    const clone = [...original];
    
    console.log(clone);           // [1, 2, 3]
    

物件

  1. 物件合併:可以將多個物件合併成一個新物件 -> 第 5 天:物件與陣列 - 物件迭代的方法 Object.assign(target, ...sources) 是一樣的,如果運用 ... 可以讓程式碼簡化也更好閱讀。
    const dog = {
      breed: "gold",
      age: 6
    };
    const cat = {
      breed: "mix",
      age: 3,
      food: "fish"
    };
    
    console.log({ ...cat, ...dog });  // [object Object] { "breed": "gold", "age": 6, "food": "fish" }
    
  2. 物件複製:可以使用擴展運算子快速複製一個物件,同時也加入新方法,然而舊的物件不會受到影響。
    const methods = {
        fn1() {
            console.log(1);
        },
        fn2() {
            console.log(1);
        },
    }
    const methods2 = {
        ...methods,
        fn3() {
            console.log(3)
        }
    }
    
    console.log(methods === methods2);          // false
    methods.fn3();                              // methods.fn3 is not a function
    

合併運算子 ??


MDN文件:空值合并运算符(??)
在 php7.0 稱為空值合併運算子 ??

合併運算子 ?? 用於處理 nullundefined 的情況,主要是預先替變數設定一個預設值,但是只有在變數的值為 nullundefined 時才使用預設值。

const value1 = null;
const value2 = "default";
const result = value1 ?? value2;

console.log(result); // 'default'

合併運算子 ?? vs 邏輯OR運算子 ||

回顧:第 2 天:基本語法和資料類型 - 🔔 0, null, undefined 差別
0, null, undefined 差別
圖片來源:Difference between non-zero value, 0, null & undefined in Javascript

邏輯OR運算子 || 會在左側的值為任何假值(如 0, '', false)時使用預設值。

const value1 = 0;
const defaultValue = "default";

console.log(value1 || defaultValue); // "default"
console.log(value1 ?? defaultValue); // 0

補充:可選串連 ?.


MDN文件:可選串連
在 php8.0 稱為可選操作符 ?->

程式碼編譯到出現這樣的紅色 alarm 一定要記得除錯,因為出現後不做任何動作,程式也不會往下繼續執行;就像 undefined 只是單純存取不到值, not define 是異常,出現 not define 一定要除錯,不然不會跑!
not defined

實戰中最常發生在生命週期的時候,在 vue3.4 中使用 computed 可能出現畫面掛載完成但是 api 資料還沒回來,tempate 取不到物件屬性,導致 F12 console 噴出 undefined...
這時候,如果用可選串連 ?. 可以避免避免在存取物件屬性時因 nullundefined 而導致的錯誤。

在學後端過程也有用到可選鏈操作符 ?. 和 nullish 合併運算符 ?? 一起使用,時機在前端給後端的參數日期是可選,但是邏輯上又要使用到日期跟當下日期比對先後,這時候就會很好用!
轉回前端的語言,大致上要表達的意思程式碼如下:

const task = {
  start_at: null
};
const now = new Date();
const startAtTime = new Date(task.start_at)?.getTime();
const shouldThrowException = !startAtTime ?? startAtTime <= now.getTime();

if (shouldThrowException) {
  console.log("任務開始不可編輯");  // "任務開始不可編輯"
} else {
  console.log("do someting...");
}

以下是前端的問號之間比較整理當作今天的收尾:

運算子(符) 語法 說明
三元運算子 condition ? exprIfTrue : exprIfFalse 判斷式為真,返回冒號左邊的值;反之右邊的值
可選串連 obj.val?.prop 物件的屬性不存在的時候,取值也不會報錯
空值合併運算符 leftExpr ?? rightExpr 左邊的值是 null 或是 undefined 就會返回右邊的值

上一篇
第 6 天:ES6 新特性 - 解構賦值與範本字面量
下一篇
第 8 天:模組化程式設計
系列文
30天 JavaScript 提升計畫:從零到精通結合2024年的創新功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言