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

在本教程中,我们将讨论用于从存储在变量中的字符串执行函数的两种方法。

让我们讨论哪种方法对于这种情况更可取且安全。

建议使用 HTML5 中的 window 对象引用当前窗口及其中的所有项目。

我们可以使用该对象在字符串中运行函数以及该函数的参数:

window["functionName"](arguments);

由于这不适用于命名空间的函数,我们可以使用以下内容:

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

这里我们建议一个灵活的例子:

func = function( args ) {
    console.log( 'Global function passed:' );
    for( let i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] );
    }
};
nameSpace = {};
nameSpace.func = function( args ) {
    console.log( 'Namespace function passed:' );
    for( let i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] ); 
    }
};
name = 'nameSpacefunc';
n_s_func = [ 'Snowden' ];
noSuchAgency = function(){};
function executeFunctionByName( functionName, context /*, args */) {
    let args, namespaces, fn;
    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( "." );
    fn = namespaces.pop();
    for( let i = 0; i < namespaces.length; i++ ) {
        context = context[ namespaces[ i ] ];
    }
    return context[ fn ].apply( context, args );
}
executeFunctionByName( 'func' );
executeFunctionByName( 'func', 100 );
executeFunctionByName( 'nameSpace.func', 'No Such Agency!' );
executeFunctionByName( 'func', nameSpace, 'No Such Agency!', [ 008, 'is the even' ] );
executeFunctionByName("nameSpace.func", window, arguments);

你可以这样称呼它:

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

还有另一种经常用于解决这种情况的方法,即 eval()。

但是,请注意,不建议使用此方法。
让我们解释一下为什么不应该使用这种方法。

我们应该避免使用它的主要和第一个原因是该方法已过时并且可能不受较新浏览器的支持。
它有一些安全、优化和调试问题。
相反,我们会在教程开始时为问题建议一个更好、更安全的解决方案。

日期:2020-06-02 22:16:17 来源:oir作者:oir