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

