【问题标题】:Call jQuery defined function via string通过字符串调用 jQuery 定义的函数
【发布时间】:2011-09-15 00:10:03
【问题描述】:

我想调用我在 jQuery 的文档就绪函数中定义的函数,但是遇到了一些麻烦。我有以下代码:

jQuery(document).ready( function($) {

    function test1() {
        alert('test1');
    }

    function test2() {
        alert('test2');
    }

    var test_call = '2';

    var fn = 'test' + test_call;

    // use fn to call test2

});

我不想使用eval,而window[fn] 似乎不起作用。这两个测试函数似乎不是窗口变量中的索引。感谢您的帮助和知识。

【问题讨论】:

  • 你是在 jsFiddle 或类似的东西上测试它吗?
  • window[fn] 将不起作用,因为您在闭包内定义函数,因此它们不会添加到全局(窗口)范围
  • 是否有一个带参数的函数不是选项?

标签: javascript jquery


【解决方案1】:

我能想到的不使用eval()或某种形式的eval(将字符串传递给setTimeout()是eval()的一种形式),就是在一个对象上注册相关的函数名,然后在该对象上查找函数名称:

jQuery(document).ready( function($) {

    function test1() {
        alert('test1');
    }

    function test2() {
        alert('test2');
    }

    // register functions on an object
    var funcList = {};
    funcList["test1"] = test1;
    funcList["test2"] = test2;


    var test_call = '2';

    var fn = 'test' + test_call;

    if (fn in funcList) {
        funcList[fn]();
    }

});

或者注册可以在函数的定义中完成。如果它们是全局函数,它们将隐式注册在 window 对象上,但它们不是全局函数,因为它们在 document.ready 处理函数的范围内:

jQuery(document).ready( function($) {

    var funcList = {};

    funcList.test1 = function test1() {
        alert('test1');
    }

    funcList.test2 = function test2() {
        alert('test2');
    }

    var test_call = '2';
    var fn = 'test' + test_call;

    if (fn in funcList) {
        funcList[fn]();
    }

});

或者,您可以将函数移动到全局范围,以便它们自动注册到窗口对象,如下所示:

function test1() {
    alert('test1');
}

function test2() {
    alert('test2');
}

jQuery(document).ready( function($) {

    var test_call = '2';
    var fn = 'test' + test_call;

    if (fn in window) {
        window[fn]();
    }

});

【讨论】:

  • 谢谢jfriend00,这是我要走的路线。我不确定是否有一个不同的全局变量(或与 jQuery 类似的东西)处理了 document.ready 中的函数。
  • document.ready 中的代码只是匿名函数中的代码,因此没有可以在那里处理的命名范围。在那里声明的函数只是局部函数(与局部变量相同)。您可以将函数定义移动到全局范围,以便它们会自动注册到窗口对象(请参阅我刚刚添加到答案中的最后一个选项)。
【解决方案2】:

如果不是 Eval,最好的方法是使用零毫秒的 setTimeout,因为您可以将函数指定为字符串。

setTimeout('myfunction()',0,);

【讨论】:

  • 即使没有显式调用eval(),这仍然在内部使用eval(),并且会受到任何可能与eval有关的问题的影响(例如从外部源执行任意代码)。如果这很重要,这也不会在下一行代码之前同步发生。
猜你喜欢
  • 1970-01-01
  • 2020-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多