
本文详解如何让 eval() 动态执行的代码中定义的函数,能被 setInterval 安全、可靠地调用,解决模块脚本下作用域隔离导致的函数不可访问问题。
本文详解如何让 `eval()` 动态执行的代码中定义的函数,能被 `setinterval` 安全、可靠地调用,解决模块脚本下作用域隔离导致的函数不可访问问题。
在现代浏览器中,使用 <script type="module"> 加载的 JavaScript 模块具有严格的作用域隔离机制:eval() 在模块内执行时,其创建的变量和函数默认仅存在于 eval 的临时作用域中,<strong>不会泄漏到外部作用域或全局对象上。因此,直接写 eval("function example() {...}") 后尝试 setInterval(example, 10) 会报错 ReferenceError: example is not defined。</script>
✅ 正确做法是:让 eval() 返回一个包含目标函数的对象(或显式挂载到可访问作用域),再从中提取函数引用传给 setInterval。例如:
const codeInput = document.getElementById("codearea").value;
// 推荐方式:eval 返回一个对象,函数作为其属性
const result = eval(`({ examplefunc() { console.log('tick'); } })`);
setInterval(result.examplefunc, 1000); // ✅ 正确:引用对象上的方法
⚠️ 注意事项:
- ❌ 避免 eval("function example() {...}"); setInterval(example, 10) —— 模块中无效;
- ❌ 不要依赖 window.examplefunc(模块中 eval 不自动挂载到 window);
- ✅ 若需多个函数,统一组织在对象中:eval("({ init(){...}, update(){...}, render(){...} })");
- ⚠️ eval() 存在严重安全风险(如 XSS),仅限可信、本地调试场景使用;生产环境应改用 Function 构造器或预编译方案;
- ? setInterval 频率过低(如 10ms)易造成性能压力,建议根据实际需求设为 16ms(≈60fps)或更高。
总结:eval() 本身不产生“可导出”的函数,关键在于控制返回值结构——让其返回一个可索引的对象,再通过点语法获取函数引用。这既绕过了模块作用域限制,又保持了调用的明确性与可控性。











