当我将JavaScript函数的名称作为字符串时,如何执行它

时间:2021-12-15 16:57:55

I have the name of a function in JavaScript as a string. How do I convert that into a function pointer so I can call it later?

在JavaScript中,函数的名称是字符串。如何将它转换成函数指针以便稍后调用?

Depending on the circumstances, I may need to pass various arguments into the method too.

根据不同的情况,我可能还需要将各种参数传递到方法中。

Some of the functions may take the form of namespace.namespace.function(args[...]).

有些函数可以采用namespace.namespace.function(args[…])的形式。

30 个解决方案

#1


1207  

Don't use eval unless you absolutely, positively have no other choice.

不要使用eval,除非你绝对、肯定地别无选择。

As has been mentioned, using something like this would be the best way to do it:

如前所述,使用这样的东西是最好的方法:

window["functionName"](arguments);

That, however, will not work with a namespace'd function:

然而,这并不适用于命名空间d函数:

window["My.Namespace.functionName"](arguments); // fail

This is how you would do that:

你会这样做:

window["My"]["Namespace"]["functionName"](arguments); // succeeds

In order to make that easier and provide some flexibility, here is a convenience function:

为了使之更容易,并提供一些灵活性,这里有一个便利功能:

function executeFunctionByName(functionName, context /*, args */) {
  var args = Array.prototype.slice.call(arguments, 2);
  var namespaces = functionName.split(".");
  var func = namespaces.pop();
  for(var i = 0; i < namespaces.length; i++) {
    context = context[namespaces[i]];
  }
  return context[func].apply(context, args);
}

You would call it like so:

你可以这样称呼它:

executeFunctionByName("My.Namespace.functionName", window, arguments);

Note, you can pass in whatever context you want, so this would do the same as above:

注意,您可以传入任何您想要的上下文,因此这将与上面的内容相同:

executeFunctionByName("Namespace.functionName", My, arguments);

#2


88  

Just thought I'd post a slightly altered version of Jason Bunting's very helpful function.

我只是想发布一个稍微改动过的杰森·邦廷的非常有用的功能。

First, I have simplified the first statement by supplying a second parameter to slice(). The original version was working fine in all browsers except IE.

首先,我通过向slice()提供第二个参数简化了第一条语句。除了IE,最初的版本在所有浏览器中运行良好。

Second, I have replaced this with context in the return statement; otherwise, this was always pointing to window when the target function was being executed.

第二,我用返回语句中的上下文替换了它;否则,在执行目标函数时,它总是指向窗口。

function executeFunctionByName(functionName, context /*, args */) {
    var args = Array.prototype.slice.call(arguments, 2);
    var namespaces = functionName.split(".");
    var func = namespaces.pop();
    for (var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
    }
    return context[func].apply(context, args);
}

#3


50  

The answer to this other question shows you how to do that: Javascript equivalent of Python's locals()?

另一个问题的答案向您展示了如何做到这一点:Javascript等效于Python的local ()?

Basically, you can say

基本上,你可以说

window["foo"](arg1, arg2);

or as many others have suggested, you can just use eval:

或者像很多人建议的那样,你可以使用eval:

eval(fname)(arg1, arg2);

although this is extremely unsafe unless you're absolutely sure about what you're eval-ing.

虽然这是非常不安全的,除非你绝对确定你在做什么。

#4


43  

Could you not just do this:

你能不能这样做:

var codeToExecute = "My.Namespace.functionName()";
var tmpFunc = new Function(codeToExecute);
tmpFunc();

You can also execute any other JavaScript using this method.

您还可以使用此方法执行任何其他JavaScript。

#5


29  

I think an elegant way of doing this is by defining your functions in a hash object. Then you can have a reference to those functions from the hash using the string. e.g.

我认为一种优雅的方法是通过在一个散列对象中定义函数。然后您可以使用字符串从散列中获得对这些函数的引用。如。

var customObject = {
  customFunction: function(param){...}
};

Then you can call:

然后你可以叫:

customObject['customFunction'](param);

Where customFunction will be a string matching a function defined in your object.

customFunction将是匹配对象中定义的函数的字符串。

#6


21  

Two things:

两件事:

  • avoid eval, it's terribly dangerous and slow

    避免使用eval,它是非常危险和缓慢的

  • secondly it doesn't matter where your function exists, "global" -ness is irrelevant. x.y.foo() can be enabled through x.y['foo']() or x['y']['foo']() or even window['x']['y']['foo'](). You can chain indefinitely like this.

    第二,无论函数存在于何处,“全局”是无关的。x.y.foo()可以通过x.y(“foo”)()或x(y)(“foo”)()甚至窗口[x][y](“foo”)()。你可以像这样无限期地锁链。

#7


18  

With ES6 you could to access class methods by name:

使用ES6,您可以按名称访问类方法:

class X {
  method1(){
    console.log("1");
  }
  method2(){
    this['method1']();
    console.log("2");
  }
}
let x  = new X();
x['method2']();

the output would be:

的输出是:

1
2

#8


12  

You just need convert your string to a pointer by window[<method name>]. example:

只需通过窗口[ <方法名> ]将字符串转换为指针即可。例子:

var function_name = "string";
function_name = window[function_name];

and now you can use it like a pointer.

现在你可以像使用指针一样使用它。

#9


12  

All the answers assume that the functions can be accessed through global scope (aka window). However, the OP did not make this assumption.

所有答案都假设函数可以通过全局作用域(即窗口)访问。然而,OP并没有做出这样的假设。

If the functions live in a local scope (aka closure) and are not referenced by some other local object, bad luck: You have to use eval() AFAIK, see dynamically call local function in javascript

如果函数存在于局部范围(也称为闭包),并且没有被其他本地对象引用,那么坏运气:您必须使用eval() AFAIK,在javascript中动态调用本地函数。

#10


8  

If you want to call a function of an object instead of a global function with window["functionName"]. You can do it like;

如果您想调用对象的函数而不是带有窗口的全局函数["functionName"]。你可以这样做;

var myObject=new Object();
myObject["functionName"](arguments);

Example:

例子:

var now=new Date();
now["getFullYear"]()

#11


8  

Here is my contribution to Jason Bunting's / Alex Nazarov's excellent answers, where I include error checking requested by Crashalot.

这是我对Jason Bunting / Alex Nazarov的出色回答的贡献,其中包括Crashalot要求的错误检查。

Given this (contrived) preamble:

鉴于这种(做作)序言:

a = function( args ) {
    console.log( 'global func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] );
    }
};
ns = {};
ns.a = function( args ) {
    console.log( 'namespace func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] ); 
    }
};
name = 'nsa';
n_s_a = [ 'Snowden' ];
noSuchAgency = function(){};

then the following function:

然后下面的功能:

function executeFunctionByName( functionName, context /*, args */ ) {
    var args, namespaces, func;

    if( typeof functionName === 'undefined' ) { throw 'function name not specified'; }

    if( typeof eval( functionName ) !== 'function' ) { throw functionName + ' is not a function'; }

    if( typeof context !== 'undefined' ) { 
        if( typeof context === 'object' && context instanceof Array === false ) { 
            if( typeof context[ functionName ] !== 'function' ) {
                throw context + '.' + functionName + ' is not a function';
            }
            args = Array.prototype.slice.call( arguments, 2 );

        } else {
            args = Array.prototype.slice.call( arguments, 1 );
            context = window;
        }

    } else {
        context = window;
    }

    namespaces = functionName.split( "." );
    func = namespaces.pop();

    for( var i = 0; i < namespaces.length; i++ ) {
        context = context[ namespaces[ i ] ];
    }

    return context[ func ].apply( context, args );
}

will allow you to call a javascript function by name stored in a string, either namespaced or global, with or without arguments (including Array objects), providing feedback on any errors encountered (hopefully catching them).

将允许您按存储在字符串中的名称(名称空间或全局)调用一个javascript函数,使用或不使用参数(包括数组对象),对遇到的错误提供反馈(希望捕获它们)。

The sample output shows how it works:

示例输出显示了它是如何工作的:

// calling a global function without parms
executeFunctionByName( 'a' );
  /* OUTPUT:
  global func passed:
  */

// calling a global function passing a number (with implicit window context)
executeFunctionByName( 'a', 123 );
  /* OUTPUT:
  global func passed:
  -> 123
  */

// calling a namespaced function without parms
executeFunctionByName( 'ns.a' );
  /* OUTPUT:
  namespace func passed:
  */

// calling a namespaced function passing a string literal
executeFunctionByName( 'ns.a', 'No Such Agency!' );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  */

// calling a namespaced function, with explicit context as separate arg, passing a string literal and array 
executeFunctionByName( 'a', ns, 'No Such Agency!', [ 007, 'is the man' ] );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  -> 7,is the man
  */

// calling a global function passing a string variable (with implicit window context)
executeFunctionByName( 'a', name );
  /* OUTPUT:
  global func passed:
  -> nsa
  */

// calling a non-existing function via string literal
executeFunctionByName( 'n_s_a' );
  /* OUTPUT:
  Uncaught n_s_a is not a function
  */

// calling a non-existing function by string variable
executeFunctionByName( n_s_a );
  /* OUTPUT:
  Uncaught Snowden is not a function
  */

// calling an existing function with the wrong namespace reference
executeFunctionByName( 'a', {} );
  /* OUTPUT:
  Uncaught [object Object].a is not a function
  */

// calling no function
executeFunctionByName();
  /* OUTPUT:
  Uncaught function name not specified
  */

// calling by empty string
executeFunctionByName( '' );
  /* OUTPUT:
  Uncaught  is not a function
  */

// calling an existing global function with a namespace reference
executeFunctionByName( 'noSuchAgency', ns );
  /* OUTPUT:
  Uncaught [object Object].noSuchAgency is not a function
  */

#12


7  

BE CAREFUL!!!

小心! ! !

One should try to avoid calling a function by string in JavaScript for two reasons:

人们应该尽量避免在JavaScript中通过字符串调用函数,原因有两个:

Reason 1: Some code obfuscators will wreck your code as they will change the function names, making the string invalid.

原因1:一些代码混淆器会破坏您的代码,因为它们将更改函数名,使字符串无效。

Reason 2: It is much harder to maintain code that uses this methodology as it is much harder to locate usages of the methods called by a string.

理由2:维护使用这种方法的代码要困难得多,因为查找字符串调用的方法的用法要困难得多。

#13


4  

Surprised to see no mention of setTimeout.

惊讶地发现没有提到setTimeout。

To run a function without arguments:

运行一个没有参数的函数:

var functionWithoutArguments = function(){
    console.log("Executing functionWithoutArguments");
}
setTimeout("functionWithoutArguments()", 0);

To run function with arguments:

以参数运行函数:

var functionWithArguments = function(arg1, arg2) {
    console.log("Executing functionWithArguments", arg1, arg2);
}
setTimeout("functionWithArguments(10, 20)");

To run deeply namespaced function:

运行名称空间极深的函数:

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}
setTimeout("_very._deeply._defined._function(40,50)", 0);

#14


2  

One more detail on Jason and Alex's posts. I found it helpful to add a default value to context. Just put context = context == undefined? window:context; at the beginning of the function. You can change window to whatever your preferred context is, and then you won't need to pass in the same variable each time you call this in your default context.

关于Jason和Alex的文章还有一个细节。我发现向上下文添加默认值很有帮助。把context = context = undefined?窗口:上下文;在函数的开始。您可以将窗口更改为您喜欢的上下文,然后在默认上下文中每次调用时都不需要传入相同的变量。

#15


2  

There's a very similar thing in my code. I have a server-generated string which contains a function name which I need to pass as a callback for a 3rd party library. So I have a code that takes the string and returns a "pointer" to the function, or null if it isn't found.

在我的代码中有一个非常类似的东西。我有一个服务器生成的字符串,它包含一个函数名,我需要将其作为第三方库的回调传递。所以我有一个代码,它获取字符串并返回函数的“指针”,如果没有找到,则返回null。

My solution was very similar to "Jason Bunting's very helpful function" *, although it doesn't auto-execute, and the context is always on the window. But this can be easily modified.

我的解决方案非常类似于“Jason Bunting的非常有用的函数”*,尽管它不会自动执行,而且上下文总是在窗口上。但这很容易修改。

Hopefully this will be helpful to someone.

希望这对某人有帮助。

/**
 * Converts a string containing a function or object method name to a function pointer.
 * @param  string   func
 * @return function
 */
function getFuncFromString(func) {
    // if already a function, return
    if (typeof func === 'function') return func;

    // if string, try to find function or method of object (of "obj.func" format)
    if (typeof func === 'string') {
        if (!func.length) return null;
        var target = window;
        var func = func.split('.');
        while (func.length) {
            var ns = func.shift();
            if (typeof target[ns] === 'undefined') return null;
            target = target[ns];
        }
        if (typeof target === 'function') return target;
    }

    // return null if could not parse
    return null;
}

#16


2  

So, like others said, definitely the best option is:

所以,就像其他人说的,最好的选择肯定是:

window['myfunction'](arguments)

And like Jason Bunting said, it won't work if the name of your function includes an object:

就像Jason Bunting说的那样,如果你的函数名包含一个对象,它就不会工作:

window['myobject.myfunction'](arguments); // won't work
window['myobject']['myfunction'](arguments); // will work

So here's my version of a function that will execute all functions by name (including an object or not):

这是我的函数版本,它将按名称(包括对象或不包括对象)执行所有函数:

my = {
    code : {
        is : {
            nice : function(a, b){ alert(a + "," + b); }
        }
    }
};

guy = function(){ alert('awesome'); }

function executeFunctionByName(str, args)
{
    var arr = str.split('.');
    var fn = window[ arr[0] ];
    
    for (var i = 1; i < arr.length; i++)
    { fn = fn[ arr[i] ]; }
    fn.apply(window, args);
}

executeFunctionByName('my.code.is.nice', ['arg1', 'arg2']);
executeFunctionByName('guy');

#17


2  

  let t0 = () => { alert('red0') }
  var t1 = () =>{ alert('red1') }
  var t2 = () =>{ alert('red2') }
  var t3 = () =>{ alert('red3') }
  var t4 = () =>{ alert('red4') }
  var t5 = () =>{ alert('red5') }
  var t6 = () =>{ alert('red6') }

  function getSelection(type) {
    var evalSelection = {
      'title0': t0,
      'title1': t1,
      'title2': t2,
      'title3': t3,
      'title4': t4,
      'title5': t5,
      'title6': t6,
      'default': function() {
        return 'Default';
      }
    };
    return (evalSelection[type] || evalSelection['default'])();
  }
  getSelection('title1');

A more OOP solution ...

一个更加面向对象的解决方案……

#18


1  

There too some very helpful way.

还有一些非常有用的方法。

http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx

http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx

var arrayMaker = {  
    someProperty: 'some value here',  
    make: function (arg1, arg2) {  
        return [ this, arg1, arg2 ];  
    },
    execute: function_name
};

#19


1  

I can't resist mentioning another trick, which helps if you have an unknown number of arguments that are also being passed as part of the string containing the function name. For example:

我不得不提到另一个技巧,如果您有数量未知的参数,这些参数也作为包含函数名的字符串的一部分进行传递,那么这个技巧将有所帮助。例如:

var annoyingstring = 'call_my_func(123, true, "blah")';

var annoyingstring = ' callmy_func (123, true, "blah");

If your Javascript is running on a HTML page, all you need is an invisible link; you can pass a string into the onclick attribute, and the call the click method.

如果你的Javascript在HTML页面上运行,你只需要一个不可见的链接;可以将字符串传递到onclick属性,并调用click方法。

<a href="#" id="link_secret"><!-- invisible --></a>

< a href = " # " id = " link_secret " > < !——看不见的> < / >

$('#link_secret').attr('onclick', annoyingstring);
$('#link_secret').click();

Or create the <a> element at runtime.

或者在运行时创建元素。

#20


1  

Easiest way is to access it like has element

最简单的方法是像have元素一样访问它

window.ClientSideValidations.forms.location_form

is same as

是一样的

window.ClientSideValidations.forms['location_form']

#21


0  

To add to Jason Bunting's answer, if you're using nodejs or something (and this works in dom js, too), you could use this instead of window (and remember: eval is evil:

要补充Jason Bunting的回答,如果您使用nodejs或其他东西(这在dom js中也适用),您可以使用这个而不是window(请记住:eval是evil:

this['fun'+'ctionName']();

#22


0  

Without using eval('function()') you could to create a new function using new Function(strName). The below code was tested using FF, Chrome, IE.

不使用eval('function()')),您可以使用new function(strName)创建一个新函数。下面的代码是用FF, Chrome来测试的。

<html>
<body>
<button onclick="test()">Try it</button>
</body>
</html>
<script type="text/javascript">

  function test() {
    try {    
        var fnName = "myFunction()";
        var fn = new Function(fnName);
        fn();
      } catch (err) {
        console.log("error:"+err.message);
      }
  }

  function myFunction() {
    console.log('Executing myFunction()');
  }

</script>

#23


0  

use this

function executeFunctionByName(functionName, context /*, args */) {
      var args = [].slice.call(arguments).splice(2);
      var namespaces = functionName.split(".");
      var func = namespaces.pop();
      for(var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
      }
      return context[func].apply(context, args);
    }

#24


0  

Look basic:

基本:

var namefunction = 'jspure'; // String

function jspure(msg1 = '', msg2 = '') { 
  console.log(msg1+(msg2!=''?'/'+msg2:''));
} // multiple argument

// Results ur test
window[namefunction]('hello','hello again'); // something...
eval[namefunction] = 'hello'; // use string or something, but its eval just one argument and not exist multiple

Exist other type function is class and look example nils petersohn

存在其他类型函数是类,看例子nils petersohn

#25


0  

Thanks for the very helpful answer. I'm using Jason Bunting's function in my projects.

谢谢你的帮助。我在我的项目中使用Jason Bunting的函数。

I extended it to use it with an optional timeout, because the normal way to set a timeout wont work. See abhishekisnot's question

我将它扩展为使用可选的超时,因为设置超时的常规方法不起作用。看到abhishekisnot的问题

function executeFunctionByName(functionName, context, timeout /*, args */ ) {
	var args = Array.prototype.slice.call(arguments, 3);
	var namespaces = functionName.split(".");
	var func = namespaces.pop();
	for (var i = 0; i < namespaces.length; i++) {
		context = context[namespaces[i]];
	}
	var timeoutID = setTimeout(
		function(){ context[func].apply(context, args)},
		timeout
	);
    return timeoutID;
}

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}

console.log('now wait')
executeFunctionByName("_very._deeply._defined._function", window, 2000, 40, 50 );

#26


0  

There are several executeByName functions here which works fine, unless name contains square brackets - issue I ran into - as I have dynamically generated names. So above functions will fail on names like

这里有几个executeByName函数可以正常工作,除非name包含方括号(我遇到的问题),因为我已经动态生成了名称。所以上面的函数会在名字上失败

app.widget['872LfCHc']['toggleFolders']

app.widget[872 lfchc][' toggleFolders ']

As a remedy, I've made function to take this into account too, maybe someone will find it usefull:

作为一种补救措施,我也考虑到了这个问题,也许有人会发现它是有用的:

Generated from CoffeeScript:

CoffeeScript产生:

var executeByName = function(name, context) {
  var args, func, i, j, k, len, len1, n, normalizedName, ns;
  if (context == null) {
    context = window;
  }
  args = Array.prototype.slice.call(arguments, 2);
  normalizedName = name.replace(/[\]'"]/g, '').replace(/\[/g, '.');
  ns = normalizedName.split(".");
  func = context;
  for (i = j = 0, len = ns.length; j < len; i = ++j) {
    n = ns[i];
    func = func[n];
  }
  ns.pop();
  for (i = k = 0, len1 = ns.length; k < len1; i = ++k) {
    n = ns[i];
    context = context[n];
  }
  if (typeof func !== 'function') {
    throw new TypeError('Cannot execute function ' + name);
  }
  return func.apply(context, args);
}

For better readability check also CoffeeScript version:

为了更好的可读性,还需要检查CoffeeScript版本:

executeByName = (name, context = window) ->
    args = Array.prototype.slice.call(arguments, 2)
    normalizedName = name.replace(/[\]'"]/g, '').replace(/\[/g, '.')
    ns = normalizedName.split "."
    func = context
    for n, i in ns
        func = func[n]

    ns.pop()
    for n, i in ns
        context = context[n];
    if typeof func != 'function'
        throw new TypeError 'Cannot execute function ' + name
    func.apply(context, args)

#27


0  

You can call javascript function within the eval("functionname as string") either. Like below: (eval is pure javascript function)

您也可以在eval(“functionname as string”)中调用javascript函数。如下所示:(eval是纯javascript函数)

function testfunc(){
    return "hello world";
}

$( document ).ready(function() {

     $("div").html(eval("testfunc"));
});

Working example: https://jsfiddle.net/suatatan/24ms0fna/4/

工作示例:https://jsfiddle.net/suatatan/24ms0fna/4/

#28


0  

all you have to do is use a context or define a new context where you function(s) reside. you are not limited to window["f"]();

您所要做的就是使用上下文或定义一个新的上下文,其中您的函数位于其中。您不受限于窗口["f"]();

here is an example of how I use some dynamic invocation for some REST services.

下面是如何使用一些REST服务的动态调用的示例。

/* 
Author: Hugo Reyes
@ www.teamsrunner.com

*/

    (function ( W, D) { // enclose it as self invoking function to avoid name collisions.


    // to call function1 as string
    // initialize your FunctionHUB as your namespace - context
    // you can use W["functionX"](), if you want to call a function at the window scope.
    var container = new FunctionHUB();


    // call a function1 by name with one parameter.

    container["function1"](' Hugo ');


    // call a function2 by name.
    container["function2"](' Hugo Leon');


    // OO style class
    function FunctionHUB() {

        this.function1 = function (name) {

            console.log('Hi ' + name + ' inside function 1')
        }

        this.function2 = function (name) {

            console.log('Hi' + name + ' inside function 2 ')
        }
    }

})(window, document); // in case you need window context inside your namespace.

If you want to generate the entire function from a string, that's a different answer. also please notice that you are not limited to a single name space, if you name space exists as my.name.space.for.functions.etc.etc.etc the last branch of your name space contains the function as my.name.space.for.functions.etc.etc["function"]();

如果你想从一个字符串中生成整个函数,那是不同的答案。还请注意,如果您的名称空间存在于my.name.space.for.functions.etc.等等,那么您的名称空间的最后一个分支包含的函数为my.name.space.for.functions.etc.等["function"]();

Hope it helps. H.

希望它可以帮助。H。

#29


0  

This is working for me:

这对我很有效:

var command = "Add";
var tempFunction = new Function("Arg1","Arg2", "window." + command + "(Arg1,Arg2)");
tempFunction(x,y);

I hope this works.

我希望这工作。

#30


0  

Since eval() is evil, and new Function() is not the most efficient way to achieve this, here is a quick JS function that returns the function from its name in string.

因为eval()是有害的,并且new Function()不是实现这一点的最有效的方法,这里有一个快速的JS函数,它从字符串中的函数名返回函数。

  • Works for namespace'd functions
  • 适用于名称空间功能
  • Fallbacks to null-function in case of null/undefined string
  • 在null/未定义字符串的情况下,返回null函数。
  • Fallbacks to null-function if function not found
  • 如果未找到函数,则回退到null-function

    function convertStringtoFunction(functionName){

        var nullFunc = function(){}; // Fallback Null-Function
        var ret = window; // Top level namespace

        // If null/undefined string, then return a Null-Function
        if(functionName==null) return nullFunc;

        // Convert string to function name
        functionName.split('.').forEach(function(key){ ret = ret[key]; });

        // If function name is not available, then return a Null-Function else the actual function
        return (ret==null ? nullFunc : ret);

    }

Usage:

用法:


    convertStringtoFunction("level1.midLevel.myFunction")(arg1, arg2, ...);

#1


1207  

Don't use eval unless you absolutely, positively have no other choice.

不要使用eval,除非你绝对、肯定地别无选择。

As has been mentioned, using something like this would be the best way to do it:

如前所述,使用这样的东西是最好的方法:

window["functionName"](arguments);

That, however, will not work with a namespace'd function:

然而,这并不适用于命名空间d函数:

window["My.Namespace.functionName"](arguments); // fail

This is how you would do that:

你会这样做:

window["My"]["Namespace"]["functionName"](arguments); // succeeds

In order to make that easier and provide some flexibility, here is a convenience function:

为了使之更容易,并提供一些灵活性,这里有一个便利功能:

function executeFunctionByName(functionName, context /*, args */) {
  var args = Array.prototype.slice.call(arguments, 2);
  var namespaces = functionName.split(".");
  var func = namespaces.pop();
  for(var i = 0; i < namespaces.length; i++) {
    context = context[namespaces[i]];
  }
  return context[func].apply(context, args);
}

You would call it like so:

你可以这样称呼它:

executeFunctionByName("My.Namespace.functionName", window, arguments);

Note, you can pass in whatever context you want, so this would do the same as above:

注意,您可以传入任何您想要的上下文,因此这将与上面的内容相同:

executeFunctionByName("Namespace.functionName", My, arguments);

#2


88  

Just thought I'd post a slightly altered version of Jason Bunting's very helpful function.

我只是想发布一个稍微改动过的杰森·邦廷的非常有用的功能。

First, I have simplified the first statement by supplying a second parameter to slice(). The original version was working fine in all browsers except IE.

首先,我通过向slice()提供第二个参数简化了第一条语句。除了IE,最初的版本在所有浏览器中运行良好。

Second, I have replaced this with context in the return statement; otherwise, this was always pointing to window when the target function was being executed.

第二,我用返回语句中的上下文替换了它;否则,在执行目标函数时,它总是指向窗口。

function executeFunctionByName(functionName, context /*, args */) {
    var args = Array.prototype.slice.call(arguments, 2);
    var namespaces = functionName.split(".");
    var func = namespaces.pop();
    for (var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
    }
    return context[func].apply(context, args);
}

#3


50  

The answer to this other question shows you how to do that: Javascript equivalent of Python's locals()?

另一个问题的答案向您展示了如何做到这一点:Javascript等效于Python的local ()?

Basically, you can say

基本上,你可以说

window["foo"](arg1, arg2);

or as many others have suggested, you can just use eval:

或者像很多人建议的那样,你可以使用eval:

eval(fname)(arg1, arg2);

although this is extremely unsafe unless you're absolutely sure about what you're eval-ing.

虽然这是非常不安全的,除非你绝对确定你在做什么。

#4


43  

Could you not just do this:

你能不能这样做:

var codeToExecute = "My.Namespace.functionName()";
var tmpFunc = new Function(codeToExecute);
tmpFunc();

You can also execute any other JavaScript using this method.

您还可以使用此方法执行任何其他JavaScript。

#5


29  

I think an elegant way of doing this is by defining your functions in a hash object. Then you can have a reference to those functions from the hash using the string. e.g.

我认为一种优雅的方法是通过在一个散列对象中定义函数。然后您可以使用字符串从散列中获得对这些函数的引用。如。

var customObject = {
  customFunction: function(param){...}
};

Then you can call:

然后你可以叫:

customObject['customFunction'](param);

Where customFunction will be a string matching a function defined in your object.

customFunction将是匹配对象中定义的函数的字符串。

#6


21  

Two things:

两件事:

  • avoid eval, it's terribly dangerous and slow

    避免使用eval,它是非常危险和缓慢的

  • secondly it doesn't matter where your function exists, "global" -ness is irrelevant. x.y.foo() can be enabled through x.y['foo']() or x['y']['foo']() or even window['x']['y']['foo'](). You can chain indefinitely like this.

    第二,无论函数存在于何处,“全局”是无关的。x.y.foo()可以通过x.y(“foo”)()或x(y)(“foo”)()甚至窗口[x][y](“foo”)()。你可以像这样无限期地锁链。

#7


18  

With ES6 you could to access class methods by name:

使用ES6,您可以按名称访问类方法:

class X {
  method1(){
    console.log("1");
  }
  method2(){
    this['method1']();
    console.log("2");
  }
}
let x  = new X();
x['method2']();

the output would be:

的输出是:

1
2

#8


12  

You just need convert your string to a pointer by window[<method name>]. example:

只需通过窗口[ <方法名> ]将字符串转换为指针即可。例子:

var function_name = "string";
function_name = window[function_name];

and now you can use it like a pointer.

现在你可以像使用指针一样使用它。

#9


12  

All the answers assume that the functions can be accessed through global scope (aka window). However, the OP did not make this assumption.

所有答案都假设函数可以通过全局作用域(即窗口)访问。然而,OP并没有做出这样的假设。

If the functions live in a local scope (aka closure) and are not referenced by some other local object, bad luck: You have to use eval() AFAIK, see dynamically call local function in javascript

如果函数存在于局部范围(也称为闭包),并且没有被其他本地对象引用,那么坏运气:您必须使用eval() AFAIK,在javascript中动态调用本地函数。

#10


8  

If you want to call a function of an object instead of a global function with window["functionName"]. You can do it like;

如果您想调用对象的函数而不是带有窗口的全局函数["functionName"]。你可以这样做;

var myObject=new Object();
myObject["functionName"](arguments);

Example:

例子:

var now=new Date();
now["getFullYear"]()

#11


8  

Here is my contribution to Jason Bunting's / Alex Nazarov's excellent answers, where I include error checking requested by Crashalot.

这是我对Jason Bunting / Alex Nazarov的出色回答的贡献,其中包括Crashalot要求的错误检查。

Given this (contrived) preamble:

鉴于这种(做作)序言:

a = function( args ) {
    console.log( 'global func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] );
    }
};
ns = {};
ns.a = function( args ) {
    console.log( 'namespace func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] ); 
    }
};
name = 'nsa';
n_s_a = [ 'Snowden' ];
noSuchAgency = function(){};

then the following function:

然后下面的功能:

function executeFunctionByName( functionName, context /*, args */ ) {
    var args, namespaces, func;

    if( typeof functionName === 'undefined' ) { throw 'function name not specified'; }

    if( typeof eval( functionName ) !== 'function' ) { throw functionName + ' is not a function'; }

    if( typeof context !== 'undefined' ) { 
        if( typeof context === 'object' && context instanceof Array === false ) { 
            if( typeof context[ functionName ] !== 'function' ) {
                throw context + '.' + functionName + ' is not a function';
            }
            args = Array.prototype.slice.call( arguments, 2 );

        } else {
            args = Array.prototype.slice.call( arguments, 1 );
            context = window;
        }

    } else {
        context = window;
    }

    namespaces = functionName.split( "." );
    func = namespaces.pop();

    for( var i = 0; i < namespaces.length; i++ ) {
        context = context[ namespaces[ i ] ];
    }

    return context[ func ].apply( context, args );
}

will allow you to call a javascript function by name stored in a string, either namespaced or global, with or without arguments (including Array objects), providing feedback on any errors encountered (hopefully catching them).

将允许您按存储在字符串中的名称(名称空间或全局)调用一个javascript函数,使用或不使用参数(包括数组对象),对遇到的错误提供反馈(希望捕获它们)。

The sample output shows how it works:

示例输出显示了它是如何工作的:

// calling a global function without parms
executeFunctionByName( 'a' );
  /* OUTPUT:
  global func passed:
  */

// calling a global function passing a number (with implicit window context)
executeFunctionByName( 'a', 123 );
  /* OUTPUT:
  global func passed:
  -> 123
  */

// calling a namespaced function without parms
executeFunctionByName( 'ns.a' );
  /* OUTPUT:
  namespace func passed:
  */

// calling a namespaced function passing a string literal
executeFunctionByName( 'ns.a', 'No Such Agency!' );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  */

// calling a namespaced function, with explicit context as separate arg, passing a string literal and array 
executeFunctionByName( 'a', ns, 'No Such Agency!', [ 007, 'is the man' ] );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  -> 7,is the man
  */

// calling a global function passing a string variable (with implicit window context)
executeFunctionByName( 'a', name );
  /* OUTPUT:
  global func passed:
  -> nsa
  */

// calling a non-existing function via string literal
executeFunctionByName( 'n_s_a' );
  /* OUTPUT:
  Uncaught n_s_a is not a function
  */

// calling a non-existing function by string variable
executeFunctionByName( n_s_a );
  /* OUTPUT:
  Uncaught Snowden is not a function
  */

// calling an existing function with the wrong namespace reference
executeFunctionByName( 'a', {} );
  /* OUTPUT:
  Uncaught [object Object].a is not a function
  */

// calling no function
executeFunctionByName();
  /* OUTPUT:
  Uncaught function name not specified
  */

// calling by empty string
executeFunctionByName( '' );
  /* OUTPUT:
  Uncaught  is not a function
  */

// calling an existing global function with a namespace reference
executeFunctionByName( 'noSuchAgency', ns );
  /* OUTPUT:
  Uncaught [object Object].noSuchAgency is not a function
  */

#12


7  

BE CAREFUL!!!

小心! ! !

One should try to avoid calling a function by string in JavaScript for two reasons:

人们应该尽量避免在JavaScript中通过字符串调用函数,原因有两个:

Reason 1: Some code obfuscators will wreck your code as they will change the function names, making the string invalid.

原因1:一些代码混淆器会破坏您的代码,因为它们将更改函数名,使字符串无效。

Reason 2: It is much harder to maintain code that uses this methodology as it is much harder to locate usages of the methods called by a string.

理由2:维护使用这种方法的代码要困难得多,因为查找字符串调用的方法的用法要困难得多。

#13


4  

Surprised to see no mention of setTimeout.

惊讶地发现没有提到setTimeout。

To run a function without arguments:

运行一个没有参数的函数:

var functionWithoutArguments = function(){
    console.log("Executing functionWithoutArguments");
}
setTimeout("functionWithoutArguments()", 0);

To run function with arguments:

以参数运行函数:

var functionWithArguments = function(arg1, arg2) {
    console.log("Executing functionWithArguments", arg1, arg2);
}
setTimeout("functionWithArguments(10, 20)");

To run deeply namespaced function:

运行名称空间极深的函数:

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}
setTimeout("_very._deeply._defined._function(40,50)", 0);

#14


2  

One more detail on Jason and Alex's posts. I found it helpful to add a default value to context. Just put context = context == undefined? window:context; at the beginning of the function. You can change window to whatever your preferred context is, and then you won't need to pass in the same variable each time you call this in your default context.

关于Jason和Alex的文章还有一个细节。我发现向上下文添加默认值很有帮助。把context = context = undefined?窗口:上下文;在函数的开始。您可以将窗口更改为您喜欢的上下文,然后在默认上下文中每次调用时都不需要传入相同的变量。

#15


2  

There's a very similar thing in my code. I have a server-generated string which contains a function name which I need to pass as a callback for a 3rd party library. So I have a code that takes the string and returns a "pointer" to the function, or null if it isn't found.

在我的代码中有一个非常类似的东西。我有一个服务器生成的字符串,它包含一个函数名,我需要将其作为第三方库的回调传递。所以我有一个代码,它获取字符串并返回函数的“指针”,如果没有找到,则返回null。

My solution was very similar to "Jason Bunting's very helpful function" *, although it doesn't auto-execute, and the context is always on the window. But this can be easily modified.

我的解决方案非常类似于“Jason Bunting的非常有用的函数”*,尽管它不会自动执行,而且上下文总是在窗口上。但这很容易修改。

Hopefully this will be helpful to someone.

希望这对某人有帮助。

/**
 * Converts a string containing a function or object method name to a function pointer.
 * @param  string   func
 * @return function
 */
function getFuncFromString(func) {
    // if already a function, return
    if (typeof func === 'function') return func;

    // if string, try to find function or method of object (of "obj.func" format)
    if (typeof func === 'string') {
        if (!func.length) return null;
        var target = window;
        var func = func.split('.');
        while (func.length) {
            var ns = func.shift();
            if (typeof target[ns] === 'undefined') return null;
            target = target[ns];
        }
        if (typeof target === 'function') return target;
    }

    // return null if could not parse
    return null;
}

#16


2  

So, like others said, definitely the best option is:

所以,就像其他人说的,最好的选择肯定是:

window['myfunction'](arguments)

And like Jason Bunting said, it won't work if the name of your function includes an object:

就像Jason Bunting说的那样,如果你的函数名包含一个对象,它就不会工作:

window['myobject.myfunction'](arguments); // won't work
window['myobject']['myfunction'](arguments); // will work

So here's my version of a function that will execute all functions by name (including an object or not):

这是我的函数版本,它将按名称(包括对象或不包括对象)执行所有函数:

my = {
    code : {
        is : {
            nice : function(a, b){ alert(a + "," + b); }
        }
    }
};

guy = function(){ alert('awesome'); }

function executeFunctionByName(str, args)
{
    var arr = str.split('.');
    var fn = window[ arr[0] ];
    
    for (var i = 1; i < arr.length; i++)
    { fn = fn[ arr[i] ]; }
    fn.apply(window, args);
}

executeFunctionByName('my.code.is.nice', ['arg1', 'arg2']);
executeFunctionByName('guy');

#17


2  

  let t0 = () => { alert('red0') }
  var t1 = () =>{ alert('red1') }
  var t2 = () =>{ alert('red2') }
  var t3 = () =>{ alert('red3') }
  var t4 = () =>{ alert('red4') }
  var t5 = () =>{ alert('red5') }
  var t6 = () =>{ alert('red6') }

  function getSelection(type) {
    var evalSelection = {
      'title0': t0,
      'title1': t1,
      'title2': t2,
      'title3': t3,
      'title4': t4,
      'title5': t5,
      'title6': t6,
      'default': function() {
        return 'Default';
      }
    };
    return (evalSelection[type] || evalSelection['default'])();
  }
  getSelection('title1');

A more OOP solution ...

一个更加面向对象的解决方案……

#18


1  

There too some very helpful way.

还有一些非常有用的方法。

http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx

http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx

var arrayMaker = {  
    someProperty: 'some value here',  
    make: function (arg1, arg2) {  
        return [ this, arg1, arg2 ];  
    },
    execute: function_name
};

#19


1  

I can't resist mentioning another trick, which helps if you have an unknown number of arguments that are also being passed as part of the string containing the function name. For example:

我不得不提到另一个技巧,如果您有数量未知的参数,这些参数也作为包含函数名的字符串的一部分进行传递,那么这个技巧将有所帮助。例如:

var annoyingstring = 'call_my_func(123, true, "blah")';

var annoyingstring = ' callmy_func (123, true, "blah");

If your Javascript is running on a HTML page, all you need is an invisible link; you can pass a string into the onclick attribute, and the call the click method.

如果你的Javascript在HTML页面上运行,你只需要一个不可见的链接;可以将字符串传递到onclick属性,并调用click方法。

<a href="#" id="link_secret"><!-- invisible --></a>

< a href = " # " id = " link_secret " > < !——看不见的> < / >

$('#link_secret').attr('onclick', annoyingstring);
$('#link_secret').click();

Or create the <a> element at runtime.

或者在运行时创建元素。

#20


1  

Easiest way is to access it like has element

最简单的方法是像have元素一样访问它

window.ClientSideValidations.forms.location_form

is same as

是一样的

window.ClientSideValidations.forms['location_form']

#21


0  

To add to Jason Bunting's answer, if you're using nodejs or something (and this works in dom js, too), you could use this instead of window (and remember: eval is evil:

要补充Jason Bunting的回答,如果您使用nodejs或其他东西(这在dom js中也适用),您可以使用这个而不是window(请记住:eval是evil:

this['fun'+'ctionName']();

#22


0  

Without using eval('function()') you could to create a new function using new Function(strName). The below code was tested using FF, Chrome, IE.

不使用eval('function()')),您可以使用new function(strName)创建一个新函数。下面的代码是用FF, Chrome来测试的。

<html>
<body>
<button onclick="test()">Try it</button>
</body>
</html>
<script type="text/javascript">

  function test() {
    try {    
        var fnName = "myFunction()";
        var fn = new Function(fnName);
        fn();
      } catch (err) {
        console.log("error:"+err.message);
      }
  }

  function myFunction() {
    console.log('Executing myFunction()');
  }

</script>

#23


0  

use this

function executeFunctionByName(functionName, context /*, args */) {
      var args = [].slice.call(arguments).splice(2);
      var namespaces = functionName.split(".");
      var func = namespaces.pop();
      for(var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
      }
      return context[func].apply(context, args);
    }

#24


0  

Look basic:

基本:

var namefunction = 'jspure'; // String

function jspure(msg1 = '', msg2 = '') { 
  console.log(msg1+(msg2!=''?'/'+msg2:''));
} // multiple argument

// Results ur test
window[namefunction]('hello','hello again'); // something...
eval[namefunction] = 'hello'; // use string or something, but its eval just one argument and not exist multiple

Exist other type function is class and look example nils petersohn

存在其他类型函数是类,看例子nils petersohn

#25


0  

Thanks for the very helpful answer. I'm using Jason Bunting's function in my projects.

谢谢你的帮助。我在我的项目中使用Jason Bunting的函数。

I extended it to use it with an optional timeout, because the normal way to set a timeout wont work. See abhishekisnot's question

我将它扩展为使用可选的超时,因为设置超时的常规方法不起作用。看到abhishekisnot的问题

function executeFunctionByName(functionName, context, timeout /*, args */ ) {
	var args = Array.prototype.slice.call(arguments, 3);
	var namespaces = functionName.split(".");
	var func = namespaces.pop();
	for (var i = 0; i < namespaces.length; i++) {
		context = context[namespaces[i]];
	}
	var timeoutID = setTimeout(
		function(){ context[func].apply(context, args)},
		timeout
	);
    return timeoutID;
}

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}

console.log('now wait')
executeFunctionByName("_very._deeply._defined._function", window, 2000, 40, 50 );

#26


0  

There are several executeByName functions here which works fine, unless name contains square brackets - issue I ran into - as I have dynamically generated names. So above functions will fail on names like

这里有几个executeByName函数可以正常工作,除非name包含方括号(我遇到的问题),因为我已经动态生成了名称。所以上面的函数会在名字上失败

app.widget['872LfCHc']['toggleFolders']

app.widget[872 lfchc][' toggleFolders ']

As a remedy, I've made function to take this into account too, maybe someone will find it usefull:

作为一种补救措施,我也考虑到了这个问题,也许有人会发现它是有用的:

Generated from CoffeeScript:

CoffeeScript产生:

var executeByName = function(name, context) {
  var args, func, i, j, k, len, len1, n, normalizedName, ns;
  if (context == null) {
    context = window;
  }
  args = Array.prototype.slice.call(arguments, 2);
  normalizedName = name.replace(/[\]'"]/g, '').replace(/\[/g, '.');
  ns = normalizedName.split(".");
  func = context;
  for (i = j = 0, len = ns.length; j < len; i = ++j) {
    n = ns[i];
    func = func[n];
  }
  ns.pop();
  for (i = k = 0, len1 = ns.length; k < len1; i = ++k) {
    n = ns[i];
    context = context[n];
  }
  if (typeof func !== 'function') {
    throw new TypeError('Cannot execute function ' + name);
  }
  return func.apply(context, args);
}

For better readability check also CoffeeScript version:

为了更好的可读性,还需要检查CoffeeScript版本:

executeByName = (name, context = window) ->
    args = Array.prototype.slice.call(arguments, 2)
    normalizedName = name.replace(/[\]'"]/g, '').replace(/\[/g, '.')
    ns = normalizedName.split "."
    func = context
    for n, i in ns
        func = func[n]

    ns.pop()
    for n, i in ns
        context = context[n];
    if typeof func != 'function'
        throw new TypeError 'Cannot execute function ' + name
    func.apply(context, args)

#27


0  

You can call javascript function within the eval("functionname as string") either. Like below: (eval is pure javascript function)

您也可以在eval(“functionname as string”)中调用javascript函数。如下所示:(eval是纯javascript函数)

function testfunc(){
    return "hello world";
}

$( document ).ready(function() {

     $("div").html(eval("testfunc"));
});

Working example: https://jsfiddle.net/suatatan/24ms0fna/4/

工作示例:https://jsfiddle.net/suatatan/24ms0fna/4/

#28


0  

all you have to do is use a context or define a new context where you function(s) reside. you are not limited to window["f"]();

您所要做的就是使用上下文或定义一个新的上下文,其中您的函数位于其中。您不受限于窗口["f"]();

here is an example of how I use some dynamic invocation for some REST services.

下面是如何使用一些REST服务的动态调用的示例。

/* 
Author: Hugo Reyes
@ www.teamsrunner.com

*/

    (function ( W, D) { // enclose it as self invoking function to avoid name collisions.


    // to call function1 as string
    // initialize your FunctionHUB as your namespace - context
    // you can use W["functionX"](), if you want to call a function at the window scope.
    var container = new FunctionHUB();


    // call a function1 by name with one parameter.

    container["function1"](' Hugo ');


    // call a function2 by name.
    container["function2"](' Hugo Leon');


    // OO style class
    function FunctionHUB() {

        this.function1 = function (name) {

            console.log('Hi ' + name + ' inside function 1')
        }

        this.function2 = function (name) {

            console.log('Hi' + name + ' inside function 2 ')
        }
    }

})(window, document); // in case you need window context inside your namespace.

If you want to generate the entire function from a string, that's a different answer. also please notice that you are not limited to a single name space, if you name space exists as my.name.space.for.functions.etc.etc.etc the last branch of your name space contains the function as my.name.space.for.functions.etc.etc["function"]();

如果你想从一个字符串中生成整个函数,那是不同的答案。还请注意,如果您的名称空间存在于my.name.space.for.functions.etc.等等,那么您的名称空间的最后一个分支包含的函数为my.name.space.for.functions.etc.等["function"]();

Hope it helps. H.

希望它可以帮助。H。

#29


0  

This is working for me:

这对我很有效:

var command = "Add";
var tempFunction = new Function("Arg1","Arg2", "window." + command + "(Arg1,Arg2)");
tempFunction(x,y);

I hope this works.

我希望这工作。

#30


0  

Since eval() is evil, and new Function() is not the most efficient way to achieve this, here is a quick JS function that returns the function from its name in string.

因为eval()是有害的,并且new Function()不是实现这一点的最有效的方法,这里有一个快速的JS函数,它从字符串中的函数名返回函数。

  • Works for namespace'd functions
  • 适用于名称空间功能
  • Fallbacks to null-function in case of null/undefined string
  • 在null/未定义字符串的情况下,返回null函数。
  • Fallbacks to null-function if function not found
  • 如果未找到函数,则回退到null-function

    function convertStringtoFunction(functionName){

        var nullFunc = function(){}; // Fallback Null-Function
        var ret = window; // Top level namespace

        // If null/undefined string, then return a Null-Function
        if(functionName==null) return nullFunc;

        // Convert string to function name
        functionName.split('.').forEach(function(key){ ret = ret[key]; });

        // If function name is not available, then return a Null-Function else the actual function
        return (ret==null ? nullFunc : ret);

    }

Usage:

用法:


    convertStringtoFunction("level1.midLevel.myFunction")(arg1, arg2, ...);