Antworten:
Ich habe einen jsperf-Test für 4 verschiedene Möglichkeiten hinzugefügt, um eine Funktion aus einem String zu erstellen:
Verwenden von RegExp mit Funktionsklasse
var func = "function (a, b) { return a + b; }".parseFunction();
Verwenden der Funktionsklasse mit "return"
var func = new Function("return " + "function (a, b) { return a + b; }")();
Verwenden des offiziellen Funktionskonstruktors
var func = new Function("a", "b", "return a + b;");
Eval verwenden
eval("var func = function (a, b) { return a + b; };");
Eine bessere Möglichkeit, eine Funktion aus einer Zeichenfolge zu erstellen, ist die Verwendung von Function
:
var fn = Function("alert('hello there')");
fn();
Dies hat den Vorteil / Nachteil, dass Variablen im aktuellen Bereich (wenn nicht global) nicht für die neu erstellte Funktion gelten.
Das Übergeben von Argumenten ist ebenfalls möglich:
var addition = Function("a", "b", "return a + b;");
alert(addition(5, 3)); // shows '8'
Function
Sie den lokalen Bereich nicht verschmutzen, und dies eval
macht die Optimierung für Motoren so schwierig ... Mit dem OP-Beispiel würde ich:var fnc = Function('return '+s)();
element.onclick = function() { alert("test"); }
.
Du bist ziemlich nah dran.
//Create string representation of function
var s = "function test(){ alert(1); }";
//"Register" the function
eval(s);
//Call the function
test();
Hier ist eine funktionierende Geige .
eval
Warnung für zukünftige Suchende: eval
Kann Lücken für Hacker öffnen: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…. Wenn Sie jedoch die Gefahren kennen und diese vermeiden können, ist dies ein guter einfacher Weg Erstellen Sie eine Funktion aus einem String
Ja, die Verwendung Function
ist eine großartige Lösung, aber wir können noch einen Schritt weiter gehen und einen universellen Parser vorbereiten, der die Zeichenfolge analysiert und in eine echte JavaScript-Funktion konvertiert ...
if (typeof String.prototype.parseFunction != 'function') {
String.prototype.parseFunction = function () {
var funcReg = /function *\(([^()]*)\)[ \n\t]*{(.*)}/gmi;
var match = funcReg.exec(this.replace(/\n/g, ' '));
if(match) {
return new Function(match[1].split(','), match[2]);
}
return null;
};
}
Anwendungsbeispiele:
var func = 'function (a, b) { return a + b; }'.parseFunction();
alert(func(3,4));
func = 'function (a, b) { alert("Hello from function initiated from string!"); }'.parseFunction();
func();
hier ist jsfiddle
JavaScript
Function
var name = "foo";
// Implement it
var func = new Function("return function " + name + "(){ alert('hi there!'); };")();
// Test it
func();
// Next is TRUE
func.name === 'foo'
Quelle: http://marcosc.com/2012/03/dynamic-function-names-in-javascript/
eval
var name = "foo";
// Implement it
eval("function " + name + "() { alert('Foo'); };");
// Test it
foo();
// Next is TRUE
foo.name === 'foo'
sjsClass
https://github.com/reduardo7/sjsClass
Class.extend('newClassName', {
__constructor: function() {
// ...
}
});
var x = new newClassName();
// Next is TRUE
newClassName.name === 'newClassName'
Diese Technik mag letztendlich der Eval-Methode entsprechen, aber ich wollte sie hinzufügen, da sie für einige nützlich sein könnte.
var newCode = document.createElement("script");
newCode.text = "function newFun( a, b ) { return a + b; }";
document.body.appendChild( newCode );
Dies entspricht dem Hinzufügen dieses <script> -Elements am Ende Ihres Dokuments, z. B.:
...
<script type="text/javascript">
function newFun( a, b ) { return a + b; }
</script>
</body>
</html>
Verwenden Sie das new Function()
mit einem Return im Inneren und führen Sie es sofort aus.
var s = `function test(){
alert(1);
}`;
var new_fn = new Function("return " + s)()
console.log(new_fn)
new_fn()
Ein Beispiel mit dynamischen Argumenten:
let args = {a:1, b:2}
, fnString = 'return a + b;';
let fn = Function.apply(Function, Object.keys(args).concat(fnString));
let result = fn.apply(fn, Object.keys(args).map(key=>args[key]))