写出安全又声明式的 JavaScript——5 个函数式实战模式

我有一支技术全面、经验丰富的小型团队,专注高效交付中等规模外包项目,有需要外包项目的可以联系我

在攻击频发、状态复杂、API 诡谲的今天,“能跑”远远不够。你需要的是 安全、可维护、可演进 的代码。下面这 5 个函数式思维的实战模式,从 XSS 防护到资源清理,帮你把前后端 JS 都武装到牙齿。

1) 用 Tagged Template 挡住 XSS

问题: 直接把用户输入塞进 innerHTML,XSS 就来了。

// ❌ 易受 XSS
const userInput = '<img src=x onerror=alert(1)>';
document.body.innerHTML = `<div>${userInput}</div>`;

// ✅ 用标签模板转义
function escapeHTML(strings, ...values) {
  return strings.reduce((out, str, i) => {
    let val = values[i] ?? '';
    val = String(val)
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&#039;');
    return out + str + val;
  }, '');
}

const safeHTML = escapeHTML`<div>${userInput}</div>`;
document.body.innerHTML = safeHTML;

效果: 在写入 DOM 前统一转义危险字符,阻断注入。何时用: 无框架/微型页面里插入动态 HTML,或你自己掌管渲染管线时。


2) 用 Proxy 做声明式校验

问题: 在 class setter 里写校验又长又散。https://wxa.wxs.qq.com/tmpl/oi/base_tmpl.html

// ✅ Proxy 统一拦截
const validator = {
  set(obj, prop, value) {
    if (prop === 'age' && value < 18) throw new Error('Too young!');
    obj[prop] = value;
    return true;
  }
};

const user = new Proxy({}, validator);
user.age = 20; // OK
user.age = 15; // ❌ throw

效果: 把规则集中到一处,可复用可扩展,不侵入业务对象。何时用: 表单校验、API 入参校验、响应式状态写保护。

3) 用 BigInt 做大数/整钱精确计算

问题: 浮点数天生有误差。

// ❌ 浮点误差
0.1 + 0.2 === 0.3; // false

// ✅ BigInt 精确整数运算
const a = 100n, b = 200n;
const sum = a + b;
sum === 300n; // true

效果: 金额、计数、加密相关的整型计算零误差何时用: 金融场景(用“分”为单位)、区块/签名、超大计数。

注:BigInt 与 Number 不可混算;涉及小数用定点小数策略(放大为整数再计算)。

4) 用 Symbol.dispose(提案) 保证资源清理

问题: 忘关文件/连接 → 资源泄漏。

const using = async (resource, fn) => {
  try {
    await fn(resource);
  } finally {
    resource[Symbol.dispose]?.();
  }
};

const file = {
  [Symbol.dispose]() {
    console.log('File handle closed');
  }
};

await using(file, async (f) => {
  console.log('Using file');
});

效果: 把清理逻辑写成协议,finally 里必定执行,不怕异常中断。何时用: Node.js 长任务、边缘函数、批处理、外部资源接入。

提示:若运行环境不支持,可用约定方法 + try/finally 模拟。

5) 安全解构默认值,零空指针崩溃

问题: 对 null/undefined 解构会直接炸。

// ❌ TypeError
// const { x } = undefined;

// ✅ 提供空对象与默认值
const { x = 1 } = (maybeObj ?? {});
console.log(x); // 1

效果: 动态/可选数据结构稳态解构,避免“偶发”崩溃。何时用: API 可选字段、表单草稿、用户偏好读写。

速查清单(Pin 在工位)

  • XSS 防护:自建 escapeHTML 标签模板,所有插入先过模板
  • 声明式校验:Proxy 集中关口,规则可组合
  • 精确整数:金额/大数用 BigInt + 定点策略
  • 确定清理:协议化 dispose异常也不漏
  • 安全解构obj ?? {} + 默认值,永不空炸

结语

高手不只写“能跑”的代码,更写守护用户、经得起放大的代码。把这 5 个模式融进你的日常:

  • 更安全:先天免疫常见漏洞与泄漏;
  • 更声明式:意图即代码,降低心智负担;
  • 更可维护:规则集中、边界清晰、可测试。

今天就挑两条落地进项目,你的未来自己会感谢现在的你。
全栈AI·探索:涵盖动效、React Hooks、Vue 技巧、LLM 应用、Python 脚本等专栏,案例驱动实战学习,点击二维码了解更多详情。

声明:来自JavaScript 每日一练,仅代表创作者观点。链接:https://eyangzhen.com/3683.html

JavaScript 每日一练的头像JavaScript 每日一练

相关推荐

关注我们
关注我们
购买服务
购买服务
返回顶部