Wie verwandle ich einen String in einen JavaScript-functionsaufruf?

Ich habe eine Zeichenfolge wie:

settings.functionName + '(' + t.parentNode.id + ')'; 

dass ich in einen functionsaufruf wie folgt übersetzen möchte:

 clickedOnItem(IdofParent); 

Dies muss natürlich in JavaScript erfolgen. Wenn ich eine Warnung auf settings.functionName + '(' + t.parentNode.id + ')'; es scheint alles richtig zu machen. Ich muss nur die function aufrufen, in die es übersetzt werden würde.

Legende:

 settings.functionName = clickedOnItem t.parentNode.id = IdofParent 

Sehen, wie ich Eval hasse, und ich bin nicht allein :

 var fn = window[settings.functionName]; if(typeof fn === 'function') { fn(t.parentNode.id); } 

Edit: Als Antwort auf @ Mahans Kommentar: In diesem speziellen Fall wäre settings.functionName "clickedOnItem" . Dies würde zur Laufzeit translate var fn = window[settings.functionName]; in var fn = window["clickedOnItem"] , das einen Verweis auf die function clickedOnItem (nodeId) {} . Sobald wir eine Referenz auf eine function innerhalb einer Variablen haben, können wir diese function aufrufen, indem wir die Variable aufrufen, dh fn(t.parentNode.id) , was clickedOnItem(t.parentNode.id) , was das OP war gewollt.

Mehr vollständiges Beispiel:

 /* Somewhere: */ window.settings = { /* [..] Other settings */ functionName: 'clickedOnItem' /* , [..] More settings */ }; /* Later */ function clickedOnItem (nodeId) { /* Some cool event handling code here */ } /* Even later */ var fn = window[settings.functionName]; /* note that settings.functionName could also be written as window.settings.functionName. In this case, we use the fact that window is the implied scope of global variables. */ if(typeof fn === 'function') { fn(t.parentNode.id); } 
 window[settings.functionName](t.parentNode.id); 

Keine Notwendigkeit für ein eval ()

Hier ist eine allgemeinere Möglichkeit, dasselbe zu tun, während Bereiche unterstützt werden:

 // Get function from string, with or without scopes (by Nicolas Gauthier) window.getFunctionFromString = function(string) { var scope = window; var scopeSplit = string.split('.'); for (i = 0; i < scopeSplit.length - 1; i++) { scope = scope[scopeSplit[i]]; if (scope == undefined) return; } return scope[scopeSplit[scopeSplit.length - 1]]; } 

Hoffe, dass es einigen Leuten helfen kann.

JavaScript hat eine eval function, die einen String auswertet und als Code ausführt:

 eval(settings.functionName + '(' + t.parentNode.id + ')'); 

eval () ist die function, die Sie dazu benötigen, aber ich würde Ihnen raten, eines dieser Dinge zu versuchen, um die Verwendung von eval zu minimieren. Hoffentlich macht einer von ihnen Sinn für Sie.

Speichern Sie die function

Speichern Sie die function als function, nicht als Zeichenfolge, und verwenden Sie sie später als function. Wo Sie die function tatsächlich speichern, bleibt Ihnen überlassen.

 var funcForLater = clickedOnItem; // later is now funcForLater(t.parentNode.id); 

oder

 someObject.funcForLater = clickedOnItem; // later is now (someObject.funcForLater)(t.parentNode.id); 

Speichern Sie den functionsnamen

Selbst wenn Sie den functionsnamen als String speichern müssen, können Sie die Komplexität minimieren

 (eval(settings.functionName))(t.parentNode.id); 

Das minimiert die Menge an Javascript, die Sie erstellen und prüfen müssen.

Wörterbuch der Handler

Fügen Sie alle benötigten Aktionsfunktionen in ein Objekt ein und rufen Sie sie im Dictionary-Stil mit der Zeichenfolge auf.

 // global itemActions = { click: clickedOnItem, rightClick: rightClickedOnItem /* etc */ }; // Later... var actionName = "click"; // Or wherever you got the action name var actionToDo = itemActions[actionName]; actionToDo(t.parentNode.id); 

(Kleinere Anmerkung: Wenn Sie stattdessen hier die Syntax itemActions[actionName](t.parentNode.id); verwendet hätten, würde die function als Methode von itemActions .)

Während ich die erste Antwort mag und ich hasse eval, möchte ich hinzufügen, dass es einen anderen Weg gibt (ähnlich wie eval), also wenn du es umgehen kannst und es nicht benutzt, solltest du es besser machen. Aber in einigen Fällen möchten Sie möglicherweise vor oder nach einem Ajax-Aufruf JavaScript-Code aufrufen. Wenn Sie diesen Code in einem benutzerdefinierten Attribut anstelle von Ajax verwenden, können Sie Folgendes verwenden:

  var executeBefore = $(el).attr("data-execute-before-ajax"); if (executeBefore != "") { var fn = new Function(executeBefore); fn(); } 

Oder speichern Sie dies eventuell in einem functions-Cache, wenn Sie es möglicherweise mehrmals aufrufen müssen.

Auch hier – verwenden Sie nicht Eval oder diese Methode, wenn Sie eine andere Möglichkeit haben, dies zu tun.

Wenn settings.functionName bereits eine function ist, können Sie Folgendes tun:

 settings.functionName(t.parentNode.id); 

Ansonsten sollte dies auch funktionieren, wenn settings.functionName nur der Name der function ist:

 if (typeof window[settings.functionName] == "function") { window[settings.functionName](t.parentNode.id); } 

Ich wollte in der Lage sein, einen functionsnamen als eine Zeichenfolge zu nehmen, sie aufzurufen und ein Argument an die function zu übergeben. Ich konnte die ausgewählte Antwort für diese Frage nicht bekommen, aber diese Antwort erklärte es genau, und hier ist eine kurze Demo.

 function test_function(argument) { alert('This function ' + argument); } functionName = 'test_function'; window[functionName]('works!'); 

Dies funktioniert auch mit mehreren Argumenten.

Das hat eine Weile window['someFunctionName']() bis ich herausgefunden habe, dass das herkömmliche window['someFunctionName']() zunächst nicht für mich funktionierte. Die Namen meiner functionen wurden als AJAX-Antwort aus einer database abgerufen. Aus irgendeinem Grund wurden meine functionen außerhalb des Bereichs des Fensters deklariert. Um dies zu beheben, musste ich die functionen, von denen ich anrief, neu schreiben

 function someFunctionName() {} 

zu

 window.someFunctionName = function() {} 

und von dort konnte ich das window['someFunctionName']() mit Leichtigkeit window['someFunctionName']() . Ich hoffe, das hilft jemandem!

Basiert auf Nicolas Gauthier Antwort:

 var strng = 'someobj.someCallback'; var data = 'someData'; var func = window; var funcSplit = strng.split('.'); for(i = 0;i < funcSplit.length;i++){ //We maybe can check typeof and break the bucle if typeof != function func = func[funcSplit[i]]; } func(data); 

Ich bevorzuge etwas wie folgt:

 window.callbackClass['newFunctionName'] = function(data) { console.log(data) }; ... window.callbackClass['newFunctionName'](data); 

In Javascript, das die CommonJS-Spezifikation verwendet, wie zum Beispiel node.js, können Sie tun, was ich unten zeige. Das ist ziemlich praktisch für den Zugriff auf eine Variable durch eine Zeichenfolge, auch wenn sie nicht auf dem window definiert ist. Wenn es eine class namens MyClass , die in einem CommonJS-Modul namens MyClass.js definiert ist

 // MyClass.js var MyClass = function() { // I do stuff in here. Probably return an object return { foo: "bar" } } module.exports = MyClass; 

Sie können dann dieses nette Stück Hexerei aus einer anderen Datei namens MyOtherFile.js machen

 // MyOtherFile.js var myString = "MyClass"; var MyClass = require('./' + myString); var obj = new MyClass(); console.log(obj.foo); // returns "bar" 

Ein Grund mehr, warum CommonJS so ein Vergnügen ist.

 eval("javascript code"); 

Es wird häufig im Umgang mit JSON verwendet .