兩個新出的 JavaScript 運算子

喆星高照發表於2024-11-14

在 ECMAScript 2021(ES12)中,JavaScript 引入了新的邏輯賦值運算子 &&=??=。這些運算子將邏輯運算子與賦值運算子相結合,提供了更加簡潔、直觀的賦值方式。

雖然已經進入標準比較久了,但是我在實際開發中見到的還比較少,今天我們一起來學習下。

邏輯與賦值運算子 &&=

&&= 的工作原理

&&= 運算子是邏輯與運算子(&&)和賦值運算子(=)的結合。它的作用是:僅當左側變數為真值(truthy)時,才將右側的值賦給左側變數。傳統的寫法需要使用 if 語句或邏輯運算子,&&= 則提供了更為簡潔的方式。

傳統寫法對比:

// 使用 if 語句
if (x) {
x = y;
}

// 使用邏輯與運算子
x = x && y;

// 使用 `&&=` 運算子(ES2021)
x &&= y;

真值和假值的概念

在 JavaScript 中,以下值被認為是假值(falsy)

  • false
  • 0
  • '' (空字串)
  • null
  • undefined
  • NaN

其他所有值都被視為真值(truthy)

示例解析

示例 1:使用者登入狀態

let isLoggedIn = true;
isLoggedIn &&= getUserData(); // 如果已經登入,獲取使用者資料

function getUserData() {
return { name: 'ConardLi', age: 17 };
}

// 結果:isLoggedIn 變為 { name: 'ConardLi', age: 17 }

示例 2:庫存更新

let stock = 17;

function sell(quantity) {
stock >= quantity &&= stock - quantity;
}

sell(5); // stock 為 5
sell(17); // stock 保持為 5,因為 5 >= 17 為 false

在上述示例中,sell 函式僅在庫存足夠時才減少庫存,防止出現負庫存的情況。

應用場景

(1)條件更新屬性

let config = {
debugMode: true,
logLevel: null
};

// 僅當 debugMode 為真時,設定 logLevel
config.debugMode &&= (config.logLevel = 'verbose');

// 結果:config.logLevel 為 'verbose'

(2)鏈式判斷

let user = {
isActive: true,
hasMembership: true
};

// 僅當使用者活躍且有會員資格時,給予折扣
user.isActive &&= user.hasMembership &&= applyDiscount();

function applyDiscount() {
return '已應用折扣';
}

// 結果:user.hasMembership 變為 '已應用折扣'

空值合併賦值運算子 ??=

??= 的工作原理

??= 運算子結合了空值合併運算子(??)和賦值運算子(=)。它的作用是:僅當左側變數為 nullundefined 時,才將右側的值賦給左側變數。這有助於在變數未被初始化時提供預設值。

傳統寫法對比:

// 使用 if 語句
if (options.timeout === null || options.timeout === undefined) {
options.timeout = 3000;
}

// 使用空值合併運算子
options.timeout = options.timeout ?? 3000;

// 使用 `??=` 運算子(ES2021)
options.timeout ??= 3000;

與其他賦值方式的比較

問題:

  • 邏輯或 || 會將 0''false 等合法值視為需要賦預設值的情況,可能導致意外的結果。
let delay = 0;
delay = delay || 1000; // delay 被誤賦值為 1000

解決方案:

  • ??= 僅在變數為 nullundefined 時才賦值,避免了上述問題。
let delay = 0;
delay ??= 1000; // delay 保持為 0

使用三元運算子:

user.name = (user.name !== null && user.name !== undefined) ? user.name : 'Anonymous';

問題: 程式碼較為冗長,可讀性不高。

使用 ??=

user.name ??= 'Anonymous';

優勢: 簡潔明瞭,僅在變數為 nullundefined 時才賦值,不影響其他假值。

應用場景

??= 運算子非常適合為可能未定義的變數設定預設值,且不會干擾有效的假值。

示例:

let score = 0;
score ??= 100; // 保持為 0

let tag = '';
tag ??= 'default'; // 保持為 ''

let active = false;
active ??= true; // 保持為 false

配置預設引數:

function initializeSettings(settings) {
settings.theme ??= 'light';
settings.notificationsEnabled ??= true;
settings.autoSaveInterval ??= 300;

return settings;
}

最後

JavaScript 的 &&=??= 運算子為我們提供了更為簡潔和精確的賦值方式:

  • &&= 運算子: 僅在左側變數為真值時才進行賦值,適合用於需要在保持假值的同時,根據真值條件更新變數的場景。
  • ??= 運算子: 僅在左側變數為 nullundefined 時才進行賦值,適合用於為未定義或空值變數設定預設值的場景。

相關文章