1267 Stimmen

Wie führe ich eine JavaScript-Funktion aus, wenn ich ihren Namen als String habe?

Ich habe den Namen einer Funktion in JavaScript als String. Wie wandle ich diesen in einen Funktionszeiger um, damit ich ihn später aufrufen kann?

Je nach den Umständen kann es erforderlich sein, der Methode auch verschiedene Argumente zu übergeben.

Einige der Funktionen können die folgende Form haben namespace.namespace.function(args[...]) .

61voto

nils petersohn Punkte 2068

Mit ES6 konnte man auf Klassenmethoden über den Namen zugreifen:

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

würde die Ausgabe lauten:

1
2

30voto

annakata Punkte 72408

Zwei Dinge:

  • eval vermeiden, es ist furchtbar gefährlich und langsam

  • Zweitens spielt es keine Rolle, wo Ihre Funktion existiert, die "Globalität" ist irrelevant. x.y.foo() kann aktiviert werden durch x.y['foo']() o x['y']['foo']() oder sogar window['x']['y']['foo']() . Sie können auf diese Weise eine unbegrenzte Kette bilden.

28voto

Wolfgang Kuehn Punkte 10819

Alle Antworten gehen davon aus, dass auf die Funktionen über den globalen Bereich (Fenster) zugegriffen werden kann. Der Auftraggeber hat diese Annahme jedoch nicht getroffen.

Wenn die Funktionen in einem lokalen Bereich (auch Closure genannt) leben und nicht von einem anderen lokalen Objekt referenziert werden, haben Sie Pech: Sie müssen eval() AFAIK, siehe dynamischer Aufruf einer lokalen Funktion in Javascript

24voto

Zibri Punkte 7918

Je nachdem, wo Sie sich befinden, können Sie diese auch verwenden:

this["funcname"]();
self["funcname"]();
window["funcname"]();
top["funcname"]();
globalThis["funcname"]();

oder, in nodejs

global["funcname"]()

15voto

Mac Punkte 1157

Hier ist mein Beitrag zu den ausgezeichneten Antworten von Jason Bunting/Alex Nazarov, in dem ich die von Crashalot geforderte Fehlerprüfung einfüge.

Angesichts dieser (erfundenen) Präambel:

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(){};

dann die folgende Funktion:

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 );
}

ermöglicht es Ihnen, eine Javascript-Funktion durch den Namen in einer Zeichenfolge gespeichert, entweder namespaced oder global, mit oder ohne Argumente (einschließlich Array-Objekte), die Rückmeldung über alle aufgetretenen Fehler (hoffentlich fangen sie) aufrufen.

Die Beispielausgabe zeigt, wie es funktioniert:

// 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
  */

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X