本文讲解如何让 eval() 执行的代码中声明的函数能被 setInterval 安全、可靠地调用,解决模块脚本下作用域隔离导致的函数不可访问问题。核心思路是将函数挂载到一个显式对象上,而非依赖全局或局部作用域。
本文讲解如何让 `eval()` 执行的代码中声明的函数能被 `setinterval` 安全、可靠地调用,解决模块脚本下作用域隔离导致的函数不可访问问题。核心思路是将函数挂载到一个显式对象上,而非依赖全局或局部作用域。
在使用 <script type="module"> 的现代前端开发中,eval() 执行的代码默认运行在独立的临时作用域内,其内部声明的变量和函数<strong>不会自动暴露到全局或外层模块作用域,因此直接写 eval("function example() {...}"); setInterval(example, 10) 会报错 ReferenceError: example is not defined。</script>
✅ 正确做法:让 eval() 返回一个包含函数的对象,再通过属性访问调用:
const codeInput = document.getElementById("codearea").value;
// 示例输入内容(注意:必须返回一个对象,且函数作为其属性)
// const input = "({ examplefunc: () => { console.log('tick'); } })";
try {
const result = eval(`(${codeInput})`); // 加括号确保表达式求值,返回对象
if (typeof result.examplefunc === 'function') {
const intervalId = setInterval(result.examplefunc, 10);
// 可选:添加清理逻辑(如需停止)
// clearInterval(intervalId);
} else {
console.error("eval 结果中不存在可调用的 examplefunc 方法");
}
} catch (err) {
console.error("eval 执行失败:", err.message);
}
? 关键要点:
- ❌ 避免 eval("function examplefunc(){...}") —— 这只是函数声明语句,eval 返回 undefined;
- ✅ 推荐 eval("({ examplefunc: function(){...} })") 或 eval("(() => ({ examplefunc: () => {...} }))()") —— 确保 eval 返回一个对象;
- ? 不要将函数挂载到 window(如 window.examplefunc = ...),这在模块脚本中无效,且存在安全与污染风险;
- ⚠️ 安全警示:eval() 执行用户输入代码具有极高安全风险(XSS、任意代码执行),生产环境严禁直接 eval 用户可控字符串;如必须动态执行逻辑,请改用 Function 构造函数(更可控)或 Web Worker + 沙箱方案。
? 替代建议(更安全):
// 更安全的动态函数创建方式(仍需谨慎校验输入)
const fnBody = document.getElementById("codearea").value.trim();
const safeFunc = new Function('return ' + fnBody)(); // 要求 fnBody 是返回对象的表达式
if (typeof safeFunc.examplefunc === 'function') {
setInterval(safeFunc.examplefunc, 10);
}
总结:eval() 本身不“导出”任何标识符;要跨作用域使用其内部函数,唯一可靠方式是让它显式返回结构化数据(如对象),再通过属性访问获取函数引用——这是作用域隔离下的标准解法。











