应系统化处理属性存在性检查,优先用可选链(?.)和空值合并(??),配合类型守卫、结构校验与显式真值判断,并结合TypeScript严格模式降低运行时风险。

属性是否存在检查,是前端和通用业务逻辑中高频出现的脆弱点。评审时若只看“能跑通”,容易忽略深层隐患——比如空值崩溃、链式访问报错、类型误判导致的逻辑跳变。优化核心不是简单加个 &&,而是从**意图明确性、防御层级、可读一致性**三方面系统处理。
优先使用可选链(?.)替代多层 && 判断
传统写法如 if (obj && obj.user && obj.user.profile && obj.user.profile.name) 冗长且易漏、难维护。可选链天然适配属性存在性检查:
- 直接替换为
if (obj?.user?.profile?.name),语义清晰,执行安全; - 配合空值合并操作符(??)提供默认值:
const name = data?.user?.name ?? '匿名用户';; - 注意:仅适用于运行时环境支持(现代浏览器、TypeScript 编译目标 ≥ ES2020);若需兼容旧环境,应搭配 Babel 插件或明确标注构建约束。
对不确定结构的对象,用类型守卫或结构校验前置
当对象来源不可控(如 API 响应、localStorage 解析、第三方 SDK 返回),仅靠 ?. 不足以保障后续逻辑安全。评审时应关注是否做了结构可信度确认:
使用 Scrapfly SDK(scrapfly-sdk)在 TypeScript 或 JavaScript 中进行网页抓取,用于用户请求抓取 URL、绕过反爬虫防护、渲染页面等场景。
- 简单字段校验可用
in操作符或typeof判断:if ('id' in user && typeof user.id === 'string'); - 复杂嵌套建议封装校验函数,如
isValidUserProfile(data),返回布尔值并附带类型提示(TypeScript 中可配合类型谓词data is UserProfile); - 避免在多个地方重复写
?.xxx?.yyy,而应在数据流入层(如请求拦截器、状态初始化)做一次归一化处理。
禁止隐式真值判断,显式声明检查意图
像 if (obj.prop) 这类写法看似简洁,但会把 0、''、false 等合法值误判为“不存在”,引发逻辑错误。评审中应要求:
- 区分“属性是否存在”和“属性是否有有效值”:
✘ 错误示范:if (user.age) showAge();
✔ 正确做法:if ('age' in user)或user.age !== undefined; - 对数值/字符串等基础类型,按业务语义判断:
Number.isFinite(user.age)、user.name?.trim(); - 注释说明判断目的,例如:
// 确保字段已定义,不关心其是否为空字符串。
结合 TypeScript 编译时检查减少运行时风险
评审时顺手看一眼类型定义是否与运行时行为一致:
- 接口中用
?标记可选属性,强制调用方处理缺失情况; - 避免
any或unknown泄露到关键路径,尤其在解构或响应处理时; - 开启
strictNullChecks和exactOptionalPropertyTypes,让编译器捕获潜在的未检查分支。

















