作为前端开发者,我们每天都在与各种数据打交道。判空、取值、赋默认值…这些看似简单的操作,却经常让我们的代码充满了冗长的 if-else 判断。
可选链操作符 (?.) - 告别深层嵌套的噩梦
传统写法的痛点
还记得那些让人头疼的深层对象访问吗?
// 传统写法:层层判断 if (user && user.profile && user.profile.address && user.profile.address.city) { console.log(user.profile.address.city); } // 或者使用 try-catch try { const city = user.profile.address.city; console.log(city); } catch (error) { console.log('数据不存在'); }
可选链的优雅解决方案
// 使用可选链:一行搞定! console.log(user?.profile?.address?.city); // 如果任何一层为 null 或 undefined,直接返回 undefined // 不会抛出错误!
空值合并操作符 (??) - 智能默认值设置
与 || 操作符的区别
这是很多开发者容易混淆的地方:
const config ={ theme:'', timeout:0, enableCache: false }; //使用 || 的问题 const theme = config.theme ||'dark'; //'dark'(空字符串被认为是 falsy) const timeout = config.timeout || 3000; //3000(0 被认为是 falsy) const cache = config.enableCache | true; // true(false 被认为是 falsy) // 使用 ?? 的正确行为 const theme = config.theme ?? 'dark'; //''(保留空字符串) const timeout = config.timeout ?? 3000; //0(保留 0) const cache = config.enableCache ?? true; // false(保留 false)
写法对比:
让我们看看使用这些操作符前后的代码对比:
传统写法:
// 15行代码,多重嵌套 function getOrderTotal(order){ let total = 0; if(order) { if (order.items) { if (Array.isArray(order.items)) { for (let item of order.items) { if (item && item.price && item.quantity) { total += item.price * item.quantity; } } } } } return total || 0; }
现代写法:
//3 行代码,清晰易懂 function getOrderTotal(order) { return order?.items?.reduce((sum, item) => sum + (item?.price ?? 0) * (item?.quantity ?? 1), 0) ?? 0; }
最佳实践
1、 适度使用,避免过度链式调用
// 好的做法 const userName = user?.profile?.name; const userCity = user?.address?.city; // 避免过长的链式调用 const value = a?.b?.c?.d?.e?.f?.g?.h?.i?.j;
2、 结合解构赋值
const { name = '默认名称', age = 0, email } = user?.profile ?? {}; // 相当于 const name = user?.profile?.name ?? '默认名称'; const age = user?.profile?.age ?? 0; const email = user?.profile?.email;
这两个"小可爱"操作符的引入,让 JavaScript 代码变得更加简洁和安全:可选链操作符 (?.) 解决了深层对象访问的问题,空值合并操作符 (??) 提供了更精确的默认值设置。