最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
JS 原始类型操作:安全检查最佳实践
时间:2026-06-18 09:47:52 编辑:袖梨 来源:一聚教程网
JavaScript原始类型操作需防御性设计:先用x != null && typeof x === 'string'校验,禁用==,输入前置校验,冻结原生原型,封装纯函数。
JavaScript 原始类型操作本身看似简单,但若缺乏安全检查意识,极易引发隐式转换错误、类型误判、原型污染甚至 XSS 风险。真正的安全不是靠“运气”,而是通过明确的类型边界、可预测的校验逻辑和防御性设计来保障。
用 typeof + 显式 null/undefined 分离做基础类型断言
typeof 是检测原始类型的唯一可靠运行时手段,但它对 null 返回 "object"——这是必须绕过的陷阱。安全写法是先排除 null 和 undefined,再用 typeof 判定:
- 不要写
if (typeof x === 'string')就直接调用x.trim(),因为x可能为null或undefined - 正确写法:
if (x != null && typeof x === 'string')(!= null同时过滤null和undefined) - 更严谨可封装为:
const isString = x => x != null && typeof x === 'string',避免重复逻辑
禁止隐式转换,所有比较一律用 ===
原始类型间的松散比较(==)会触发不可控的类型转换,导致语义错乱:
-
'0' == false→true(字符串转数字再转布尔) -
0 == ''→true,但0 === ''→false,后者才符合直觉 - 函数参数校验、配置项判断、状态比对等场景,必须用
===或!== - ESLint 规则
valid-typeof和no-eq-null可强制拦截不安全写法
输入校验前置,拒绝“信任传入值”思维
任何接收外部数据(API 响应、表单字段、URL 参数)的原始类型操作,都需先校验再处理:
- 数字类操作前加
!isNaN(Number(input)) && isFinite(Number(input)),避免NaN、Infinity污染计算 - 字符串处理前确认非空且长度合理:
isString(input) && input.length > 0 && input.length - 布尔转换不依赖
!!value,而用显式映射:const toBoolean = x => x === true || x === 'true' || x === 1 || x === '1'
冻结原生原型,堵住全局污染入口
第三方脚本或恶意代码可能篡改 String.prototype 等,导致所有字符串方法失效:
- 在应用初始化最早阶段执行:
Object.freeze(String.prototype); Object.freeze(Number.prototype); Object.freeze(Boolean.prototype) - 注意:冻结后无法新增或修改方法,但不影响字面量调用(如
'a'.trim()),仅防覆盖 - 搭配严格模式(
"use strict")使用,进一步限制全局变量意外创建
纯函数封装校验逻辑,隔离副作用
把原始类型的安全操作收拢为不可变、无状态的工具函数,形成可复用、可测试的防护层:
- 例如:
Str.safeTrim = s => isString(s) ? s.trim() : '',不抛错、不中断流程、返回兜底值 - 所有函数只接收原始值,返回新值,不修改入参,也不读取
localStorage或document - 导出统一命名空间:
export const Types = { isString, isNumber, safeParseInt, safeTrim },避免散落各处