如何不使用eval()调用从外部文件导入的函数?
解决方案
问题核心在于ES模块的变量不会挂载到全局作用域,原代码里的eval默认在当前作用域执行,所以找不到导入的func2;而且用字符串传递函数名再执行本身就有安全风险,也不利于代码维护。以下是不用eval的替代方案:
方案1:直接传递函数引用(最推荐)
放弃传递函数名字符串,直接把函数本身作为参数传给func1,彻底规避字符串解析的问题:
// 导入func2 import { func2 } from "./xy"; window.addEventListener("click", function (event) { // 直接传入函数本身,而非字符串 func1(func2); }) function func1(callback) { // 直接调用传入的函数 callback(); }
如果需要给函数传递参数,可灵活扩展:
import { func2 } from "./xy"; window.addEventListener("click", function (event) { // 同时传入函数和所需参数 func1(func2, "hello", "world"); }) function func1(callback, ...args) { callback(...args); }
方案2:用函数映射表管理可调用函数
如果确实需要通过字符串指定调用的函数(比如动态场景),可以维护一个对象作为函数注册表,把需要调用的函数存入其中,通过字符串键访问:
// 导入函数(两种导入方式都适用) import * as myfunc from "./xy"; // 或 import { func2 } from "./xy"; // 创建函数映射表 const functionMap = { func2: func2, // 若用import * as myfunc,可写成:func2: myfunc.func2 }; window.addEventListener("click", function (event) { // 传递函数名字符串 func1("func2"); }) function func1(functionName) { const targetFunc = functionMap[functionName]; if (typeof targetFunc === "function") { targetFunc(); } else { console.error(`找不到名为${functionName}的函数`); } }
这种方式既避免了eval的安全隐患,又解决了模块作用域的问题,还能统一管理可调用函数,方便后续维护。
内容的提问来源于stack exchange,提问作者SM21
相关产品推荐
相关产品推荐

