new function不创建闭包,仅依赖显式参数和全局对象;需明确参数契约、封装执行器工厂、沙箱隔离、语法校验与异常降级。

new Function 本身不创建闭包,无法自动捕获外层变量,所谓“独立作用域”不是指它能隔离外部环境,而是指它**天然不依赖当前词法作用域,只依赖显式传入的参数和全局对象**。要构建真正可控、可复用的业务逻辑执行器,关键在于主动设计参数契约与执行上下文,而非依赖语言隐式行为。
明确参数契约,切断对外部变量的隐式依赖
动态函数必须把所有运行时需要的数据都作为参数显式声明,不能指望它读取外层 let/const 或模块变量。
- 错误写法:const calc = new Function('return a + b + x') —— x 未声明为参数,执行时若非全局变量则报错
- 正确写法:const calc = new Function('a', 'b', 'x', 'return a + b + x') —— 所有依赖变量都在参数列表中
- 实际业务中,常将整个上下文对象作为单个参数传入,例如:new Function('ctx', 'return ctx.user.id + ctx.order.total')
封装执行器工厂,统一注入受控运行环境
避免每次手动拼接 new Function 调用,改用工厂函数预设安全边界和常用能力。
- 定义白名单方法(如仅允许 Math、Date、JSON 等无副作用内置对象)
- 将业务工具函数(如 formatCurrency、isValidEmail)作为参数注入,不挂载到全局
- 示例:const createExecutor = (helpers) => (code) => new Function('helpers', `with(helpers){${code}}`)(helpers)
配合沙箱策略,限制全局访问能力
new Function 默认可访问 window、document、fetch 等高危全局对象。生产环境必须主动剥离或代理。
- 轻量级前端方案:用 Proxy 拦截 globalThis,只放行指定属性,其余返回 undefined 或抛错
- 更可靠方案:在 中执行,天然无 DOM 和网络能力
- 服务端场景:必须移交至 Node.js 的 vm2 或 isolated-vm,提供完整进程级隔离
校验与降级:防止不可信输入引发静默失败
字符串形式的函数体容易因拼写错误、参数缺失或类型错位导致运行时异常,需前置防护。
- 对 code 字符串做基础语法检查(如用 acorn 解析 AST,确认无非法语句)
- 执行前用 try/catch 包裹,并设置超时(通过 Promise.race + AbortController)
- 约定返回结构(如统一 { result, error }),避免 undefined 或原始值造成调用方逻辑断裂











