You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在eval中不使用this关键字调用非全局作用域的JS函数

解决方案

核心需求实现(无需this调用函数)

你遇到的报错原因是eval执行时作用域无法访问到类内部导入的isValidDocument变量,推荐使用更可控的new Function方案实现无this调用:

import isValidDocument from './isValidDocument'

class Test {
  execute(person) {
    // 从数据库读取用户自定义表达式
    const userExpression = 'isValidDocument(person) && person.age > 18'
    // 定义函数形参,把需要暴露给表达式的变量/函数都作为形参传入
    const runRule = new Function('isValidDocument', 'person', `return ${userExpression}`)
    // 执行时传入对应实参即可
    const evalResult = runRule(isValidDocument, person)
    console.log("Eval Result:", evalResult)
  }
}

如果一定要用eval实现,也可以在当前作用域先解构出需要用到的函数:

execute(person) {
  const { isValidDocument } = this
  const evalResult = eval('isValidDocument(person)')
}

该方案不推荐,因为eval可以访问当前作用域所有变量,风险远高于new Function。

执行环境隔离安全建议

开放用户自定义JS表达式权限前,建议按优先级落实以下安全措施:

  • 优先使用new Function替代直接eval:new Function的运行作用域仅包含全局环境和你主动传入的参数,不会泄露当前执行上下文的局部变量
  • 严格白名单控制暴露的API:仅传入表达式需要用到的函数和参数,禁止暴露全局对象、内部业务方法、数据库操作接口等敏感能力
  • 屏蔽全局敏感对象:创建函数时把所有全局敏感对象作为形参传入并赋值为undefined,避免用户访问:
    const runRule = new Function(
      'isValidDocument', 'person',
      'window', 'global', 'process', 'fetch', 'Function', 'constructor', '__proto__',
      `return ${userExpression}`
    )
    const evalResult = runRule(isValidDocument, person, ...new Array(7).fill(undefined))
    
  • 后端执行时用原生隔离能力:如果是Node.js后端执行规则,直接使用vm模块执行代码,设置超时时间避免死循环卡服务:
    const vm = require('vm')
    // 创建完全隔离的上下文
    const context = vm.createContext({
      isValidDocument,
      person
    })
    // 超时时间设为100ms,超过直接终止执行
    const evalResult = vm.runInContext(`return ${userExpression}`, context, { timeout: 100 })
    
  • 表达式语法校验:执行前先把用户表达式解析为AST,检查禁止的语法(赋值语句、函数定义、原型链访问等),不符合规则直接拒绝执行
  • 敏感逻辑统一后端执行:前端执行的规则结果仅做展示使用,涉及权限、数据校验的核心逻辑必须在后端二次校验,避免前端篡改绕过规则

内容的提问来源于stack exchange,提问作者user12227125

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 18:54:01