JavaScript雙問(wèn)號(hào)(??)操作符用法詳解
一、雙問(wèn)號(hào)操作符??的基礎(chǔ)用法
1、傳統(tǒng)方式的痛點(diǎn)
const count = 0; const result = count || 10; // 得到10,但0可能是有效值
使用||時(shí),會(huì)把所有假值 (falsy values)視為無(wú)效值,包括:0、''、false、NaN、null、undefined。這在處理數(shù)字表單、開(kāi)關(guān)狀態(tài)等場(chǎng)景時(shí)會(huì)引發(fā)問(wèn)題。
以上述案例來(lái)說(shuō),我想要count被賦值的情況下就使用count的值,要是沒(méi)有被賦值就使用默認(rèn)值10,但是當(dāng)count被初始化并賦值為0的時(shí)候,邏輯或操作符||依然會(huì)認(rèn)為是無(wú)效值,并將result賦值為10,這顯然和我預(yù)期的結(jié)果相悖。這是因?yàn)镴avaScript是一門(mén)弱類(lèi)型語(yǔ)言,會(huì)進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換。
2、雙問(wèn)號(hào)操作符??的精確判斷
同樣還是這個(gè)例子:
const count = 0; const result = count ?? 10; // 得到0,完美保留有效值
此時(shí)result的結(jié)果就是10,因?yàn)??操作符只對(duì)null和undefined這兩個(gè)原始值進(jìn)行判斷,其他假值都會(huì)被保留。這種特性使其特別適合處理以下場(chǎng)景:
- 表單輸入值(允許0或空字符串)
- 布爾類(lèi)型配置項(xiàng)
- 數(shù)字類(lèi)型參數(shù)(允許0)
3、雙問(wèn)號(hào)操作符??與邏輯或操作符||的對(duì)比
特性 | ?? 操作符 | || 操作符 |
---|---|---|
觸發(fā)條件 | 僅 null/undefined | 所有假值 |
適用場(chǎng)景 | 精準(zhǔn)空值判斷 | 快速默認(rèn)值設(shè)置 |
處理 0 和 '' | 保留有效值 | 覆蓋為默認(rèn)值 |
處理 false | 保留布爾值 | 覆蓋為默認(rèn)值 |
二、復(fù)雜場(chǎng)景下的空值處理
1、深層嵌套對(duì)象的默認(rèn)值
結(jié)合可選鏈操作符(?.),可以安全地處理多層嵌套對(duì)象的屬性訪問(wèn)。
const config = { api: { v1: { endpoint: '' } } }; // 傳統(tǒng)寫(xiě)法(需要逐層判斷) const endpoint = config.api?.v1?.endpoint || 'default'; // 使用??的改進(jìn)寫(xiě)法 const endpoint = config.api?.v1?.endpoint ?? 'default';
2、函數(shù)參數(shù)的默認(rèn)值陷阱
當(dāng)函數(shù)參數(shù)需要接收布爾值時(shí),使用??可以避免意外覆蓋用戶傳入的false值。
function createPost(data) { // 錯(cuò)誤寫(xiě)法:會(huì)覆蓋有效布爾值 const isPublic = data.isPublic || true; // 正確寫(xiě)法:僅處理null/undefined const isPublic = data.isPublic ?? true; }
3、多條件回退策略
通過(guò)鏈?zhǔn)绞褂??,可以實(shí)現(xiàn)多層級(jí)的配置回退機(jī)制,這種模式在讀取環(huán)境變量時(shí)特別實(shí)用。
const theme = userConfig.theme ?? systemConfig.theme ?? process.env.THEME ?? 'light';
三、實(shí)戰(zhàn)案例解析
1、Vue組件中的Prop處理
如果disabled接收的值為false,如果使用邏輯或操作符,就會(huì)被認(rèn)為是無(wú)效值,從而使用默認(rèn)的true值。如果使用雙問(wèn)號(hào)操作符就可以避免這種情況。
<template> <input :disabled="isDisabled" /> </template> <script> export default { props: { disabled: { type: Boolean, default: undefined } }, computed: { isDisabled() { return this.disabled ?? true; } } } </script>
2、表單驗(yàn)證
就算你不允許用戶輸入空格,起碼要允許用戶輸入0和引號(hào)吧?如果使用邏輯或操作符,根本無(wú)法通過(guò)表單驗(yàn)證,使用雙問(wèn)號(hào)操作符就可以避免這種情況。
function validateForm(formData) { const errors = []; if (formData.username?.trim() ?? false) { errors.push('用戶名不能為空'); } if (formData.age ?? false) { errors.push('年齡必須填寫(xiě)'); } return errors; }
四、雙問(wèn)號(hào)操作符的性能優(yōu)勢(shì)
實(shí)際測(cè)試顯示,??在性能上與||基本持平,但在處理復(fù)雜對(duì)象時(shí)更具優(yōu)勢(shì)。這是因?yàn)殡p問(wèn)號(hào)操作符只檢查null和undefined,比||操作符的類(lèi)型轉(zhuǎn)換操作更高效。
當(dāng)然,這部分差異很小,更多的作用是展示開(kāi)發(fā)者的思維能力。
// 測(cè)試環(huán)境:Chrome 112,100萬(wàn)次運(yùn)算 console.time('||'); for (let i = 0; i < 1000000; i++) null || 10; console.timeEnd('||'); // 2.1ms console.time('??'); for (let i = 0; i < 1000000; i++) null ?? 10; console.timeEnd('??'); // 1.8ms
五、結(jié)語(yǔ)
雙問(wèn)號(hào)操作符(??)這個(gè)看似簡(jiǎn)單的語(yǔ)法糖,實(shí)則蘊(yùn)含著提升代碼健壯性的強(qiáng)大能力。在實(shí)際項(xiàng)目中,建議結(jié)合TypeScript的嚴(yán)格空值檢查,構(gòu)建更可靠的類(lèi)型安全體系。
拓展:雙問(wèn)號(hào)(??)和或運(yùn)算符(||)的區(qū)別和使用
1.?? 和 || 的區(qū)別
在 JavaScript 中,雙問(wèn)號(hào)(??)和或運(yùn)算符(||)都可以用來(lái)設(shè)置默認(rèn)值,但是它們處理 Falsy 值的方式不同。
|| 運(yùn)算符在遇到 Falsy 值時(shí)會(huì)返回第一個(gè)真值(Truthy)操作數(shù),否則返回最后一個(gè)操作數(shù)。例如:
const x = null; const y = x || "default"; console.log(y); // "default"
在上面的代碼中,變量 y 的值將是 “default”,因?yàn)?x 的值為 null,null 是一個(gè) Falsy 值,所以 y 的值返回了 “default”。
而雙問(wèn)號(hào)運(yùn)算符(??)只在左側(cè)的值為 null 或 undefined 時(shí)返回右側(cè)的值,否則返回左側(cè)的值。例如:
const x = null; const y = x ?? "default"; console.log(y); // null
在上面的代碼中,變量 y 的值將是 null,因?yàn)?x 的值為 null,而 ?? 運(yùn)算符只會(huì)在左側(cè)的值為 null 或 undefined 時(shí)返回右側(cè)的默認(rèn)值。
因此,雙問(wèn)號(hào)運(yùn)算符和或運(yùn)算符的區(qū)別在于它們?cè)谔幚?Falsy 值時(shí)的行為不同?;蜻\(yùn)算符會(huì)將 Falsy 值視為假,而雙問(wèn)號(hào)運(yùn)算符只在左側(cè)的值為 null 或 undefined 時(shí)才返回右側(cè)的默認(rèn)值。
在實(shí)際使用中,當(dāng)需要設(shè)置默認(rèn)值時(shí),可以使用雙問(wèn)號(hào)運(yùn)算符來(lái)避免將 Falsy 值視為默認(rèn)值。例如:
const x = 0; const y = x ?? 42; console.log(y); // 0
在上面的代碼中,變量 y 的值將是 0,因?yàn)?x 的值為 0,而 0 不是 Falsy 值,所以 y 的值返回了 0。如果使用或運(yùn)算符來(lái)設(shè)置默認(rèn)值,那么 y 的值將會(huì)是 42,這可能不是我們期望的結(jié)果。
總之,雙問(wèn)號(hào)運(yùn)算符可以更加準(zhǔn)確地設(shè)置默認(rèn)值,避免將 Falsy 值視為默認(rèn)值。
2.?? 和 || 的使用
在 JavaScript 中,雙問(wèn)號(hào)(“??”)被稱(chēng)為 Nullish Coalescing 運(yùn)算符,它用于處理變量值為 null 或 undefined 的情況。
具體來(lái)說(shuō),雙問(wèn)號(hào)運(yùn)算符返回其左側(cè)的操作數(shù),如果它的值是 null 或 undefined,則返回右側(cè)的操作數(shù)。例如:
const x = null; const y = x ?? "default"; console.log(y); // "default"
在上面的代碼中,變量 y 的值將是 “default”,因?yàn)?x 的值為 null,而雙問(wèn)號(hào)運(yùn)算符會(huì)返回右側(cè)的默認(rèn)值。
請(qǐng)注意,雙問(wèn)號(hào)運(yùn)算符僅在其左側(cè)的值為 null 或 undefined 時(shí)才返回右側(cè)的默認(rèn)值。如果左側(cè)的值為 “”(空字符串)、0 或 false,則左側(cè)的值仍然被視為有效值,雙問(wèn)號(hào)運(yùn)算符不會(huì)返回右側(cè)的默認(rèn)值。
例如:
const a = ""; const b = a ?? "default"; console.log(b); // ""
在上面的代碼中,變量 b 的值將是 “”,因?yàn)?a 的值為 “”,而雙問(wèn)號(hào)運(yùn)算符會(huì)將其視為有效值,不會(huì)返回右側(cè)的默認(rèn)值。
以上就是JavaScript雙問(wèn)號(hào)(??)操作符用法詳解的詳細(xì)內(nèi)容,更多關(guān)于JavaScript雙問(wèn)號(hào)??用法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于JavaScript實(shí)現(xiàn)屏幕滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了基于JavaScript實(shí)現(xiàn)屏幕滾動(dòng)效果的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01根據(jù)地區(qū)不同顯示時(shí)間的javascript代碼
根據(jù)地區(qū)不同顯示時(shí)間的javascript代碼...2007-08-08element?UI中在?el-select?與?el-tree?結(jié)合組件實(shí)現(xiàn)過(guò)程
項(xiàng)目上實(shí)現(xiàn)某個(gè)功能,使用到了?el-select?和?el-tree?組合實(shí)現(xiàn),記錄下兩者結(jié)合的實(shí)現(xiàn)過(guò)程,對(duì)?el-select?與?el-tree?結(jié)合組件實(shí)現(xiàn)過(guò)程感興趣的朋友跟隨小編一起看看吧2023-02-02layui實(shí)現(xiàn)數(shù)據(jù)表格點(diǎn)擊搜索功能
這篇文章主要為大家詳細(xì)介紹了layui實(shí)現(xiàn)數(shù)據(jù)表格點(diǎn)擊搜索功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07JavaScript實(shí)現(xiàn)拖動(dòng)對(duì)話框效果的實(shí)現(xiàn)代碼
這篇文章主要介紹了JavaScript實(shí)現(xiàn)拖動(dòng)對(duì)話框效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10JavaScript常用工具函數(shù)匯總(瀏覽器環(huán)境)
這篇文章主要匯總了JavaScript常用的工具函數(shù),幫助大家更好的理解和使用JavaScript,感興趣的朋友可以了解下2020-09-09微信小程序 調(diào)用遠(yuǎn)程接口 給全局?jǐn)?shù)組賦值代碼實(shí)例
這篇文章主要介紹了微信小程序 調(diào)用遠(yuǎn)程接口 給全局?jǐn)?shù)組賦值代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08