JavaScript作为一门不断发展的语言,总是在引入新特性来解决开发者的痛点。其中,ES2020引入的空值合并操作符(Nullish Coalescing Operator),即双问号操作符(`??`),是一个简单却极其强大的工具,彻底改变了我们处理默认值和空值的方式。 ## 基本概念:什么是??操作符 双问号操作符(??)是一个逻辑操作符,当左侧操作数为`null`或`undefined`时,返回右侧操作数,否则返回左侧操作数。这看似简单,但与我们常用的逻辑或操作符(`||`)有着本质区别。 ``` const value1 = null ?? 'default'; // 'default' const value2 = undefined ?? 'default'; // 'default' const value3 = false ?? 'default'; // false const value4 = 0 ?? 'default'; // 0 const value5 = '' ?? 'default'; // '' ``` ## ??与||的关键区别 在了解??操作符的强大之前,我们需要理解它与||操作符的区别: ``` // 使用|| const count = userCount || 10; // 当userCount为0时,count将为10 // 使用?? const count = userCount ?? 10; // 当userCount为0时,count将为0 ``` ||操作符会将所有"假值"(如`0`、`''`、`false`、`NaN`等)都视为需要使用默认值的情况,而??操作符只在值为`null`或`undefined`时才使用默认值。 ## 实际应用 ### 1. 表单处理中的默认值 ``` function processForm(data) { // 只有当值真正缺失时才使用默认值 const username = data.username ?? 'guest'; const items = data.items ?? []; const quantity = data.quantity ?? 1; // 允许quantity为0 // 处理表单逻辑... } ``` ### 2. 配置对象的深层默认值 ``` const config = { server: { port: 0, // 有效值,但为"假值" host: '' // 有效值,但为"假值" } }; const userConfig = {}; // 正确处理深层配置 const port = userConfig?.server?.port ?? config.server.port; // 0 const host = userConfig?.server?.host ?? config.server.host; // '' ``` ### 3. API响应处理  ### 4. 链式默认值 ??操作符可以链式使用,创建一个"默认值瀑布":  ### 5. 与可选链操作符(?.)完美配合 当与可选链操作符(?.)结合使用时,处理复杂嵌套对象变得异常优雅: ``` const userName = user?.profile?.preferences?.displayName ?? 'Guest'; ``` 这行代码可以安全地深入访问一个可能不存在的嵌套属性,并在任何一层为null或undefined时提供默认值。 ### 6. 条件性执行函数 ``` // 仅当handler存在时才执行,否则使用默认处理函数 (customHandler ?? defaultHandler)(event); ``` ### 7. 数组元素的默认值处理  ## 高级技巧 ### 结合解构赋值 ``` const { name, age, title = 'Developer', company = 'Unknown' } = employee ?? {}; ``` 这个模式不仅能处理employee为null/undefined的情况,还为解构出的个别属性提供默认值。 ### 在类中使用 ``` class UserPreferences { constructor(settings) { this.theme = settings?.theme ?? 'light'; this.fontSize = settings?.fontSize ?? 16; this.notifications = settings?.notifications ?? true; // 即使settings.volume为0也会被保留 this.volume = settings?.volume ?? 0.5; } } ``` ## 性能考虑 ??操作符不仅语法简洁,在某些情况下还能带来性能优势。由于它只检查null和undefined,比||操作符的类型转换操作更高效。 双问号操作符(??)虽然看似简单,却解决了JavaScript中一个长期存在的痛点:如何正确处理"空值"与"假值"的区别。 Loading... JavaScript作为一门不断发展的语言,总是在引入新特性来解决开发者的痛点。其中,ES2020引入的空值合并操作符(Nullish Coalescing Operator),即双问号操作符(`<span>??</span>`),是一个简单却极其强大的工具,彻底改变了我们处理默认值和空值的方式。 ## 基本概念:什么是??操作符 双问号操作符(??)是一个逻辑操作符,当左侧操作数为`<span>null</span>`或`<span>undefined</span>`时,返回右侧操作数,否则返回左侧操作数。这看似简单,但与我们常用的逻辑或操作符(`<span>||</span>`)有着本质区别。 ``` const value1 = null ?? 'default'; // 'default' const value2 = undefined ?? 'default'; // 'default' const value3 = false ?? 'default'; // false const value4 = 0 ?? 'default'; // 0 const value5 = '' ?? 'default'; // '' ``` ## ??与||的关键区别 在了解??操作符的强大之前,我们需要理解它与||操作符的区别: ``` // 使用|| const count = userCount || 10; // 当userCount为0时,count将为10 // 使用?? const count = userCount ?? 10; // 当userCount为0时,count将为0 ``` ||操作符会将所有"假值"(如`<span>0</span>`、`<span>''</span>`、`<span>false</span>`、`<span>NaN</span>`等)都视为需要使用默认值的情况,而??操作符只在值为`<span>null</span>`或`<span>undefined</span>`时才使用默认值。 ## 实际应用 ### 1. 表单处理中的默认值 ``` function processForm(data) { // 只有当值真正缺失时才使用默认值 const username = data.username ?? 'guest'; const items = data.items ?? []; const quantity = data.quantity ?? 1; // 允许quantity为0 // 处理表单逻辑... } ``` ### 2. 配置对象的深层默认值 ``` const config = { server: { port: 0, // 有效值,但为"假值" host: '' // 有效值,但为"假值" } }; const userConfig = {}; // 正确处理深层配置 const port = userConfig?.server?.port ?? config.server.port; // 0 const host = userConfig?.server?.host ?? config.server.host; // '' ``` ### 3. API响应处理  ### 4. 链式默认值 ??操作符可以链式使用,创建一个"默认值瀑布":  ### 5. 与可选链操作符(?.)完美配合 当与可选链操作符(?.)结合使用时,处理复杂嵌套对象变得异常优雅: ``` const userName = user?.profile?.preferences?.displayName ?? 'Guest'; ``` 这行代码可以安全地深入访问一个可能不存在的嵌套属性,并在任何一层为null或undefined时提供默认值。 ### 6. 条件性执行函数 ``` // 仅当handler存在时才执行,否则使用默认处理函数 (customHandler ?? defaultHandler)(event); ``` ### 7. 数组元素的默认值处理  ## 高级技巧 ### 结合解构赋值 ``` const { name, age, title = 'Developer', company = 'Unknown' } = employee ?? {}; ``` 这个模式不仅能处理employee为null/undefined的情况,还为解构出的个别属性提供默认值。 ### 在类中使用 ``` class UserPreferences { constructor(settings) { this.theme = settings?.theme ?? 'light'; this.fontSize = settings?.fontSize ?? 16; this.notifications = settings?.notifications ?? true; // 即使settings.volume为0也会被保留 this.volume = settings?.volume ?? 0.5; } } ``` ## 性能考虑 ??操作符不仅语法简洁,在某些情况下还能带来性能优势。由于它只检查null和undefined,比||操作符的类型转换操作更高效。 双问号操作符(??)虽然看似简单,却解决了JavaScript中一个长期存在的痛点:如何正确处理"空值"与"假值"的区别。 最后修改:2025 年 04 月 16 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏