Javascript 找不到从字符串转换的函数

Javascript cannot find a function that was converted from a string

本文关键字:函数 转换 字符串 找不到 Javascript      更新时间:2023-09-26

我正在尝试在不使用eval()的情况下将字符串转换为函数,但是每当我将函数名称传递到窗口对象并检查其类型时。Javascript似乎没有将其识别为一个函数。我总是收到我在 else 语句中定义的自定义错误消息:"Could not find function: 1->validateLogin" .

我的dom_ready原型:

dom_ready: function (inputFunc) {
    document.addEventListener("DOMContentLoaded", function () {
        try {
            inputFunc();
        } catch (e) {
            DN.errors.push(e.message);
        }
    });
},

function show_pass() {
    ...
}
function validateLogin(k) {
   ...
}
DN.DOM.dom_ready(function () {
var event_ids = [
    ["#login-form-dialog", "validateLogin", "submit", 1]
    ["#loginnotes", "validateLogin", "click", 1],
    ["#loginnotes2", "validateLogin", "click", 2],
    ["#show-pass", "show_pass", "click", ""],
]
for (var i = 0; i < event_ids.length - 1; i++) {
    var fN = window[event_ids[i][1]];

    if (typeof fN === 'function') {
        $(event_ids[i][0]).on(event_ids[i][2], function () {
            fN(event_ids[i][3]);
        })
    } else {
        console.log("Could not find function: " + i + "->" + event_ids[i][1]);
    }
}
});

导致问题的特定语法错误已在其他答案中得到解决。若要查找此类语法错误,请查看控制台中的错误。或者,通过 linter 运行代码。否则,每次忘记逗号时,您都必须发布到 SO,这似乎不是一种非常可扩展的方法。

更基本的是,不要使用给出名称的字符串来传递函数引用,然后您需要在窗口对象上查找这些名称。相反,只需传递函数引用本身(validateLogin)。与其他一些语言不同,在JS中,函数是一等公民,可以作为自身引用和传递。您的代码如下所示:

DN.DOM.dom_ready(function () {
  var event_ids = [
    ["#login-form-dialog", validateLogin, "submit", 1]
                           ^^^^^^^^^^^^^
  ...
  for (var i = 0; i < event_ids.length - 1; i++) {
    var fN = event_ids[i][1];

当然,您必须确保在执行此就绪函数时validateLogin可见。

但是,您有一个更基本的问题,它将阻止您的代码正常运行,如下所示:

$(event_ids[i][0]).on(event_ids[i][2], function () {
  fN(event_ids[i][3]);
})

在这里,匿名函数是对变量i的闭包,并且在执行它时(事件发生时),i已经达到其最大值 3。SO上有很多关于这个主题的问题和答案,但最简单的解决方案是使用 for (let i ,如果您在支持let的环境中工作。否则,请参阅此类问题。

您在event_ids的第一项之后缺少逗号:

var event_ids = [
    ["#login-form-dialog", "validateLogin", "submit", 1], // <-- missing comma
    ["#loginnotes", "validateLogin", "click", 1],
    ["#loginnotes2", "validateLogin", "click", 2],
    ["#show-pass", "show_pass", "click", ""],
]; // <-- also it is better practice to have semi-colon here