2009-01-30 9 views
47

Wie kann ich ein Ereignis mit einem Funktionsnamen verbinden, den ich als String definiert habe?Rufen Sie einen JavaScript-Funktionsnamen mit einer Zeichenfolge auf?

Ich benutze Prototype.js, obwohl dies nicht prototypisch ist.

$(inputId).observe('click', formData.fields[x].onclick); 

Dies würde dazu führen, dass JavaScript sich darüber beschwert, dass mein Handler keine Funktion ist. Ich würde es bevorzugen, wenn wir nicht eval() verwenden.

+0

möglich Duplikat von [Wie ein auszuführen JavaScript-Funktion, wenn ich den Namen als String habe] (http://stackoverflow.com/questions/359788/how-to-execute-a-jacascript-function-when-i-have-its-name-asa- String) – olibre

Antwort

79

Wenn die Funktion im globalen Bereich ist, können Sie es aus dem Fenster Objekt erhalten mit:

var myFunc = window[myFuncName]; 
+11

... oder scope [myFuncName] im Allgemeinen – annakata

+0

Yup, solange Sie irgendwo einen Griff zum Scope haben, funktioniert das – Greg

+0

Das hat mir das Leben gerettet. Danke eine Million Mal. – Alex

3
window.myFunction === window["myFunction"] 
6

... oder dieses [myFuncName];

+0

Underrated Lösung. Bitte nehmen Sie meine Upvote. – woodhead92

3

Sieht aus wie formData.fields[x].onclick enthält den Namen einer globalen Funktion? Wenn ja, versuchen Sie:

$(inputId).observe('click', window[formData.fields[x].onclick]); 
1

Wissen Sie, was die onclick-Eigenschaft enthält oder welchen Typ es ist? Ich nehme an, das ist prototypspezifisches Zeug, da "Felder" in DOM-Formularen nicht existieren.

9

Ich habe an diesem Problem gearbeitet, da ich eine Funktion wie diese brauchte. Hier ist mein Sandbox-Code, nicht gründlich getestet, kann aber ein Ausgangspunkt für andere sein. Beachten Sie, dass es einen Eval() im Code gibt, da ich nicht herausfinden konnte, wie man diesen Schritt umgehen kann, vielleicht eine Javascript-Eigenart, und das kann nicht anders gemacht werden. Lass mich wissen, ob es einen Weg gibt, Eval() hier los zu werden!

executeFunctionByName = function(functionName) 
{ 
    var args = Array.prototype.slice.call(arguments).splice(1); 
    //debug 
    console.log('args:', args); 

    var namespaces = functionName.split("."); 
    //debug 
    console.log('namespaces:', namespaces); 

    var func = namespaces.pop(); 
    //debug 
    console.log('func:', func); 

    ns = namespaces.join('.'); 
    //debug 
    console.log('namespace:', ns); 

    if(ns == '') 
    { 
     ns = 'window'; 
    } 

    ns = eval(ns); 
    //debug 
    console.log('evaled namespace:', ns); 

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


core = { 
    paragraph: { 
     titlebar: { 
      user: "ddd", 
      getUser: function(name) 
      { 
       this.user = name; 
       return this.user; 
      } 
     } 
    } 
} 

var testf = function() 
{ 
    alert('dkdkdkd'); 
} 

var x = executeFunctionByName('core.paragraph.titlebar.getUser', 'Ikon'); 
executeFunctionByName('testf'); 
+0

Um das Eval loszuwerden, können Sie die Namespaces vom Window-Objekt aus navigieren: 'var func = window; für (var i = 0; i

+0

Danke Ikon. Ich habe viele Möglichkeiten ausprobiert, diese Antwort wird mein Problem lösen. –

5

Vielleicht?

setTimeout ("myFunc()", 1); 
3

Nur ein eval würde die Arbeit machen

var call = eval("method_name").call(args); 
+0

Großartig! das hat funktioniert ... danke; Sie haben vergessen. zwischen. 'var call = eval (" mathod_name ") .aufruf (args);' – RY35

0

Wenn Sie einen String-Funktion mit Argumenten aufrufen müssen, dies tun:

window[stringFunctionName].apply(window, arrayOfArguments) 

Sie scope anstelle von window verwenden können wenn bevorzugt

0

Aktualisierung: --- verwenden ES6 Export und Import

a.js

const fn = { 
    aaa: function() { 
    //code 
    }, 
    bbb: function() { 
    //code 
    }, 
    //codes .... 
    nnn: function() { 
    //code 
    } 
} 

export default fn 

b.js

import someFn from './a' 
    //eg 
    const str1='aaa' 
    const str2 = 'bbb' 

    someFn[str1]() 

Diese Methoden oben immer nicht aus irgendwelchen Gründen empfehlen, aber sie sind wirklich bequem zu bedienen. Diese Methoden sind sicher, aber nicht wirklich praktisch zu verwenden.

  • Schalter ... Fall (oder if ... else)

    switch(str){ 
        case 'str1': 
         fn1() 
         break 
        case 'str2': 
         fn2 
         //and so on 
    } 
    
  • Put-Funktionen in einem Objekt

    const fn={ 
        str1:fn1, 
        str2:fn2 
        //and so on 
    } 
    fn[str1] //call function 
    
+0

Wie beantwortet das die Frage? –

Verwandte Themen