node.js - 检查nodejs中的另一个函数中是否存在一个函数

标签 node.js webpack

提出以下情况:

function functionExists(functionName) {
    if (typeof window[functionName] == 'function') console.log("It's a function");
}

nodejs 中的等效函数是什么?对于 functionExists哪里没有全局window变量?

具体情况:

我的具体情况使用webpack而不是nodejs ,但基本上问题是一样的。我可以使用 window在这里,但要干净地实现所有内容会太复杂,webpack 不建议这样做。将事情缓解到 window全局变量。

基本上,我有一个 PHP后端,生成 html <form>通过 data 添加一些选项属性。当页面加载时,我的 JavaScript 会初始化此 <form>并赋予它一系列功能(例如验证)。 javascript 对此表单所做的另一件事是,它解析它的数据属性,而不是正常的页面重新加载提交,而是更改表单,以便通过 ajax 提交它。向服务器请求。

当这个提交发生时,它被设置为禁用按钮和整个表单,直到我的 Ajax脚本发回响应。这是如何完成的,我有一个 Project_Form类,在初始化时将其自身附加到 jQuery提交事件,停止基本提交事件,并运行一个向 api 方法发送 ajax 请求的内部函数。 ajax 请求已设置,当收到响应时,相同的实例化类将收到此响应,因此我可以继续使用它。

当表单收到响应时,它必须对其执行某些操作。在最基本的情况下,它必须向用户显示成功消息,但有一些更复杂的情况,例如,它必须进行页面重定向(例如登录表单)。现在,它已设置为默认情况下会显示一条消息,但是当我在 PHP 中定义此表单时,我可以选择“劫持”此默认行为,而不是将 ajax 响应发送到自定义函数,这将专门解决这种情况。

当我在 PHP 中渲染表单时,我已经知道表单应在何处发送成功响应(向哪个 javascript 函数),但我只能通过字符串将此信息提供给 javascript。所以我的Project_Form类,应该获取这个字符串,并且应该尝试从中获取它将使用的函数。这就是我的问题所在。

最佳答案

除非你明确知道这是一个全局函数(在 Nodejs 中几乎不会出现这种情况),否则 NodeJS 中的函数默认作用域为模块,并且无法像在浏览器中的 window 对象那样通过字符串名称查找它们,就像无法在 Javascript 中的函数内按名称查找局部变量一样。

一般来说,不要按字符串名称传递函数。或者,如果必须的话,您需要创建一个可以检查函数名称的查找表。

我建议您在这里解释一下您要解决的真正问题,因为按字符串名称传递函数并不是您通常想要做的事情。

使用 eval() 进行一些破解,可以查看字符串是否表示作用域内的函数名称:

// Warning, you must know that the argument f (if it is a string) does not
// contain harmful Javascript code because it will be used with eval()
function isFunction(f) {
   // if already a function reference
   if (typeof f === "function") {
       return true;
   // see if string represents a function name somewhere in scope
   } else if (typeof f === "string") {
       try {
           return eval(`typeof ${f} === "function"`);
       } catch(e) {
           return false;
       }
   } else {
       return false;
   }
}

注意:这会测试该函数是否在 isFunction() 函数的范围内。如果您想测试它是否在您当前的范围内,那么您需要执行以下操作:

eval(`typeof ${f} === "function"`) 

内联在当前作用域中,以便它在您要从中进行查找的作用域中运行。

要考虑使用它,您必须知道字符串的来源是安全的并且不能包含有害代码。但是,正如我之前所说,最好以不同的方式设计您的程序,这样您就不会通过字符串名称来引用函数。

而且,这是一个可运行的代码片段,显示了它的实际情况(也适用于 Node.js 模块):

function test() {
    console.log("in test");
}

function isFunction(f) {
   // if already a function reference
   if (typeof f === "function") {
       return true;
   // see if string represents a function name somewhere in scope
   } else if (typeof f === "string") {
       try {
           return eval(`typeof ${f} === "function"`);
       } catch(e) {
           return false;
       }
   } else {
       return false;
   }
}

console.log(isFunction("test"));          // true
console.log(isFunction(test));            // true
console.log(isFunction("notAFunction"));  // false

<小时/>

问题编辑后添加更多内容

如果您只有字符串形式的函数名称,并且它指向的函数不是某个已知对象的属性,那么我知道将该字符串转换为函数引用的唯一方法是使用 eval()

您可以直接使用 eval() 执行它,例如 eval(functionName + "()"),也可以使用 eval("let fn = "+ functionName) 获取函数的引用,然后使用新定义的 fn 变量来调用该函数。

如果您控制可以引用的各种函数(因为它们是您的 Javascript),那么您可以使所有这些函数成为 Javsacript 中已知对象的属性:

 const functionDispatcher = {
      function1,
      function2,
      function3,
      function4
 }

然后,您可以从 functionDispatcher 对象引用它们,而不是使用 eval(),就像您之前使用 window 引用它们一样(除非这不是全局的),如下所示:

functionDispatcher[someFunctionName]();

这将是使用 eval() 的首选选项,因为通过不安全字符串插入随机代码的风险较小。

关于node.js - 检查nodejs中的另一个函数中是否存在一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59939098/

相关文章:

node.js - Protractor/Selenium/Jasmine 超时,除非手动启动 webdriver 管理器

javascript - Node.js .match() 方法正确使用吗?

webpack - 如何在 Svelte 编译器中使用 Rollup 或 Webpack 预处理组件 CSS 和全局样式?

javascript - Haxe + Webpack 导出空对象

node.js - Webpack 如何使用 Target 属性

node.js - 当将 Consumer.on('message,callback) 放入另一个回调中时,无法从头开始消费消息

javascript - 使用 Node.jS 驱动程序在 MongoDB 中迭代多个集合并比较结果

javascript - JSDOM:访问 iframe 内的 div

javascript - 无法从单个 .js 条目(导入多个 .scss 文件)中提取多个 .css 文件?

webpack - 如何在 webpack 配置中等待一段代码?