在就绪处理程序中使用字符串调用函数...不起作用

时间:2021-11-20 13:19:32

So you want to execute a function whose name is in a string or variable:

所以你想要执行一个名字在字符串或变量中的函数:

var fn = "foobar";

function foobar() {
    console.log('say something');
}

Answers like this - How to execute a JavaScript function when I have its name as a string - say to do this:

像这样的答案 - 当我将其名称作为字符串时如何执行JavaScript函数 - 说这样做:

window[fn](); // outputs 'say something'

But... this does not work for some reason:

但是......由于某些原因,这不起作用:

jQuery(document).ready(function($){
    var fn = "foobar";

    function foobar() {
        console.log('say something');
    }

    window[fn](); // undefined
});

This works, however:

但是,这有效:

jQuery(document).ready(function($){
    var fn = "foobar";

    window[fn](); // outputs 'say something'
});

/* I'm outside the ready handler */

function foobar() {
    console.log('say something');
}

I want to keep my functions inside that ready handler so I don't have to write a bunch of anonymous functions to define jQuery as $. How do I do that?

我希望将我的函数保留在那个就绪处理程序中,这样我就不必编写一堆匿名函数来将jQuery定义为$。我怎么做?


Update

Here's what I'm wanting to do:

这是我想要做的事情:

<div data-control="toggleNext">FAQ</div>
<div>Here's some text that will be hidden until toggled</div>

JS:

JS:

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

    function toggleNext() {
        // add ".js_toggled" to .next() element
    }

    $('[data-control]').each(function(){
        var fn = window[$(this).data('control')]; // <-- this don't werk
        if (typeof fn === 'function') fn(this);
    });

});

2 个解决方案

#1


2  

If your function is inside the ready handler, it won't be available on window unless you specifically set it as such. However, that's a bad idea anyway, just leave window out of it and define your own object local to your doc ready block.

如果你的函数在ready处理程序中,它将不会在窗口中可用,除非你专门设置它。但是,无论如何,这都是一个坏主意,只需将窗口从窗口中取出并在doc ready块中定义自己的对象。

jQuery(document).ready(function($){
    var fn = "foobar", methods = {};
    methods[fn] = function () {
        console.log('say something');
    }
    $('[data-control]').each(function(){
        var fn = methods[$(this).data('control')];
        if (typeof fn === 'function') fn(this);
    });
    //methods[fn](); 
});

#2


2  

@KevinB led me to the answer and I'll give him the accept, but I thought this was worth writing out since I imagine other folks out there would want to do something like this.

@KevinB带领我得到答案,我会给他接受,但我认为这是值得写出来的,因为我想其他人会想要做这样的事情。

Since the window object does not include functions declared inside the ready handler (that is, without explicitly calling window['functionName'] = function() {...}), you can define a local object and call it instead:

由于window对象不包含在ready处理程序中声明的函数(也就是说,没有显式调用window ['functionName'] = function(){...}),你可以定义一个本地对象并调用它:

HTML:

HTML:

<div data-control="toggleNext">FAQ</div>
<div>Here's some text that will be hidden until toggled</div>

JS:

JS:

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

    var myFuncs = {

        toggleNext : function(me) {
            // add ".js_toggled" to $(me).next() element
        },

        doSomethingCool : function() {
            // you'd better make it good
        }
    }

    $('[data-control]').each(function(){

        var funcName = $(this).data('control'),
            fn = myFuncs[funcName];
        if (typeof fn === 'function')
            fn(this);

    });

});

I dunno, am I the only one that finds this useful?

我不知道,我是唯一一个发现这个有用的人吗?

#1


2  

If your function is inside the ready handler, it won't be available on window unless you specifically set it as such. However, that's a bad idea anyway, just leave window out of it and define your own object local to your doc ready block.

如果你的函数在ready处理程序中,它将不会在窗口中可用,除非你专门设置它。但是,无论如何,这都是一个坏主意,只需将窗口从窗口中取出并在doc ready块中定义自己的对象。

jQuery(document).ready(function($){
    var fn = "foobar", methods = {};
    methods[fn] = function () {
        console.log('say something');
    }
    $('[data-control]').each(function(){
        var fn = methods[$(this).data('control')];
        if (typeof fn === 'function') fn(this);
    });
    //methods[fn](); 
});

#2


2  

@KevinB led me to the answer and I'll give him the accept, but I thought this was worth writing out since I imagine other folks out there would want to do something like this.

@KevinB带领我得到答案,我会给他接受,但我认为这是值得写出来的,因为我想其他人会想要做这样的事情。

Since the window object does not include functions declared inside the ready handler (that is, without explicitly calling window['functionName'] = function() {...}), you can define a local object and call it instead:

由于window对象不包含在ready处理程序中声明的函数(也就是说,没有显式调用window ['functionName'] = function(){...}),你可以定义一个本地对象并调用它:

HTML:

HTML:

<div data-control="toggleNext">FAQ</div>
<div>Here's some text that will be hidden until toggled</div>

JS:

JS:

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

    var myFuncs = {

        toggleNext : function(me) {
            // add ".js_toggled" to $(me).next() element
        },

        doSomethingCool : function() {
            // you'd better make it good
        }
    }

    $('[data-control]').each(function(){

        var funcName = $(this).data('control'),
            fn = myFuncs[funcName];
        if (typeof fn === 'function')
            fn(this);

    });

});

I dunno, am I the only one that finds this useful?

我不知道,我是唯一一个发现这个有用的人吗?