可选链机制(?.)在 JavaScript 中出现,以方便安全地访问可能未定义的对象的属性和方法。在 TypeScript 中,它特别有用,因为可以帮助避免与访问 undefined 或 null 的属性或方法相关的运行时错误。
在可选链出现之前,开发者必须手动检查每个嵌套对象层级的存在性,这使得代码冗长且难以阅读:
if (obj && obj.a && obj.a.b) { // ... }
访问未定义对象的嵌套属性时可能会出现运行时错误:Cannot read property 'x' of undefined。此外,冗长的检查链会使代码的维护和理解变得困难。
可选链(?.)允许访问嵌套属性、方法或数组元素,如果链中任何部分为 null 或 undefined,则自动返回 undefined。
代码示例:
interface User { name: string; address?: { city?: string; }; } const user: User = { name: 'Ivan' }; console.log(user.address?.city); // undefined
关键特性:
T | undefined,TypeScript 编译器会考虑这一点并帮助避免错误。可选链可以在赋值运算符的左侧使用吗?例如:user.address?.city = 'Moscow'?
不可以,可选链不能在赋值表达式的左侧使用,这将引发编译错误。可选链仅在读取时有效,而不用于写入。
可以使用可选链调用方法吗,如果对象本身可能未定义?例如:user?.logInfo()?
可以,如果对象在方法调用的前面可能是 undefined/null,则调用 user?.logInfo() 不会引发错误,且如果 user 未定义将简单返回 undefined。
user?.logInfo(); // 如果 user 已定义,则调用 logInfo,否则不做任何操作
可选链与旧式 && 运算符(例如:user && user.address && user.address.city)有什么区别?
可选链更简洁,适用于所有类型(包括方法和数组),而且 TypeScript 在类型检查时会考虑可选链。重要的是,使用 && 运算符时,您可能意外地得到不是真/假或 undefined 的嵌套值。而可选链保证要么返回预期的类型,要么返回 undefined,这在类型推导时会得到体现。
undefined/null 的变量上使用可选链(多余且无用的代码)。在代码中,即使变量在业务逻辑上始终被定义,也存在冗长的可选链:
order?.customer?.address?.city = 'London';
优点:
缺点:
仅在处理外部数据或值确实可能未定义的地方使用可选链:
const city = apiResponse?.info?.location?.city || 'Unknown';
优点:
缺点: