在 ES6 及其之後的規格中,擴展運算子和合併運算子簡化程式碼編寫,提高了程式碼的可讀性和維護性。
其實,學後端的這幾週發現 php 也有相同的運算子,使用方法和原理幾乎是一樣的,有點他鄉遇故知的感動!
擴展運算子
...
:用於展開數組或對象,在函數呼叫、數組合併、對象合併等場景中非常有用。
合併運算子??
:用於處理null
或undefined
的情況,為變數提供預設值。
...
擴展運算子 ...
用於將 array 或 object 展開,應用於函數呼叫、數組構造和物件合併的地方,簡單來說,這個運算子不管是陣列還是物件都可以使用,有點像淺拷貝的原理!
陣列
const numbers = [1, 2, 3];
function sum(a, b, c) {
return a + b + c;
}
console.log(sum(...numbers)); // 6
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]
const original = [1, 2, 3];
const clone = [...original];
console.log(clone); // [1, 2, 3]
物件
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" }
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 稱為空值合併運算子??
合併運算子 ??
用於處理 null
或 undefined
的情況,主要是預先替變數設定一個預設值,但是只有在變數的值為 null
或 undefined
時才使用預設值。
const value1 = null;
const value2 = "default";
const result = value1 ?? value2;
console.log(result); // 'default'
合併運算子 ??
vs 邏輯OR運算子 ||
回顧:第 2 天:基本語法和資料類型 - 🔔 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
一定要除錯,不然不會跑!
實戰中最常發生在生命週期的時候,在 vue3.4 中使用 computed
可能出現畫面掛載完成但是 api 資料還沒回來,tempate 取不到物件屬性,導致 F12 console 噴出 undefined...
這時候,如果用可選串連 ?.
可以避免避免在存取物件屬性時因 null
或 undefined
而導致的錯誤。
在學後端過程也有用到可選鏈操作符 ?.
和 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 就會返回右邊的值 |