js原始类型操作不主动抛异常,但null/undefined、nan/infinity、代理对字符串等边界输入在隐式装箱或对象式访问时会触发typeerror;测试应聚焦高危组合的防御能力而非基础运算。

JS 原始类型操作本身不主动抛异常,但边界输入触发的隐式装箱或非法访问会引发 TypeError。异常处理的边界测试,核心不是覆盖所有值,而是精准识别并验证那些“看似合法、实则危险”的输入组合。
重点覆盖的高危边界输入
这些值单独使用无害,但一旦进入对象式操作上下文,极易出错:
-
null 和 undefined:调用方法(
undefined.toString())、访问属性(null.length)、解构(const {x} = null)都会立即抛TypeError -
数字类型中的特殊值:对
NaN或Infinity调用.toFixed()不报错,但对NaN调用.toString(2)会抛错;-0在某些方法中行为与0不同(如Object.is(-0, 0)返回false) -
字符串中的代理对与空值:长度为 0 的字符串
""、全空白字符串"\t\n "、含 Unicode 代理对的 emoji(如"??")在.length、.charAt()、正则匹配中表现各异,部分旧引擎会因越界访问抛错 -
布尔与数字混用场景:
true.valueOf()返回true,但true.foo报错;0被装箱后调用.toString()合法,而0..toString()(带双点)语法错误,属于解析阶段问题,不在运行时测试范畴
测试目标函数的防御能力
不测“会不会错”,而测“是否稳得住”——验证工具函数能否在边界输入下保持行为可预期:
- 对
isString(x)类型守卫函数,传入null、undefined、Symbol('a')、new String(''),断言返回严格true或false,且不抛错 - 对
toStringSafe(x)这类转换函数,传入null应返回"null"或预设默认值(如""),而非崩溃;传入123n(BigInt)需明确支持或拒绝,不能静默失败 - 解构赋值相关逻辑:测试
const { name } = obj || {}与const { name = 'guest' } = obj在obj为null、undefined、{}、{ name: null }时的实际结果,确认是否符合业务语义
避免无效测试与误判
原始类型的基础运算和比较本身不会抛异常,测试它们是否“抛错”是徒劳的:
-
10 / 0→Infinity,合法,不抛错 -
"abc" + null→"abcnull",字符串隐式转换,合法 -
NaN == NaN→false,比较结果为 false,不是异常 -
typeof undefined→"undefined",始终安全,无需 try-catch 包裹
验证异常捕获策略的有效性
仅在真正需要的地方加 try/catch,并确保它能正确区分和响应:
- 模拟第三方数据:用
JSON.parse('{ "user": null }')后尝试data.user.getName(),验证catch是否只捕获TypeError,忽略其他错误类型 - 检查日志或 fallback 行为:在 catch 块中修改状态变量或调用监控上报,断言该副作用确实执行
- 对比防御式写法:将
try/catch替换为?.或??,确认两者在相同输入下输出一致,且后者性能更优、代码更简洁











