提出以下情况:
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/