可选链(?.)和空值合并(??)是构建防御性javascript代码的核心手段,用于安全访问嵌套属性、调用方法及提供默认值,避免因null/undefined导致的typeerror;同时需配合类型校验、白名单控制与对象冻结等措施保障健壮性。

构建防御性 JavaScript 代码,核心不是“等出错再修”,而是从访问对象属性的第一行起就预设风险——因为 undefined、null、不存在的嵌套键、被篡改的原型链,都可能让 a.b.c.d 直接抛出 Cannot read property 'c' of undefined。
用可选链(?.)和空值合并(??)代替手动判断
这是现代 JS 最简洁有效的属性防护手段,避免冗长的 if (a && a.b && a.b.c)。
-
obj?.prop:安全读取属性,遇到null或undefined立即返回undefined,不报错 -
obj?.method?.():安全调用方法,只在方法存在且为函数时执行 -
value ?? 'default':仅当value是null或undefined时才使用默认值(注意:0、false、''仍会被保留)
对关键输入做类型与结构校验
不能假设传入的对象一定有某个字段,尤其来自 API、URL 参数或 localStorage 的数据。
- 检查是否存在:用
hasOwnProperty或in判断字段是否在对象自身上(避开原型污染) - 验证类型:用
typeof、Array.isArray()、Number.isFinite()等明确断言,不依赖隐式转换 - 清理字符串:对用户输入调用
.trim(),防止空格干扰判断;数值输入用Number()+isNaN()双重确认
冻结关键配置对象,防止运行时篡改
对于权限列表、常量映射、API 路径等不应被修改的数据,主动锁定结构。
-
Object.freeze(obj):禁止添加、删除、修改属性(浅冻结,嵌套对象仍可变) - 更彻底的防护:
Object.defineProperty(obj, 'prop', { writable: false, configurable: false }) - 创建不可变副本:
const safeConfig = structuredClone(originalConfig)(支持嵌套冻结)
避免依赖全局或动态属性名带来的不确定性
像 window[userInput]、obj[untrustedKey] 这类写法极易引发越权或注入,必须加白名单控制。
- 白名单校验:只允许预定义的 key 字符串,例如
['name', 'email', 'avatar'] - 拒绝任意字符串拼接:
el.innerHTML = '<div>' + data[key] + '</div>'→ 改用textContent或 DOMPurify - 敏感操作禁止用字符串构造函数:
new Function(userCode)、eval()、setTimeout(string, ...)全部禁用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











