Yanıtlar:
Dizeden bir işlev oluşturmanın 4 farklı yolu için bir jsperf testi ekledim:
RegExp'i Function sınıfıyla kullanma
var func = "function (a, b) { return a + b; }".parseFunction();
Function sınıfını "return" ile kullanma
var func = new Function("return " + "function (a, b) { return a + b; }")();
Resmi İşlev yapıcısını kullanma
var func = new Function("a", "b", "return a + b;");
Eval kullanma
eval("var func = function (a, b) { return a + b; };");
Bir dizeden işlev oluşturmanın daha iyi bir yolu şunu kullanmaktır Function:
var fn = Function("alert('hello there')");
fn();
Bunun bir avantajı / dezavantajı, mevcut kapsamdaki değişkenlerin (global değilse) yeni oluşturulan fonksiyona uygulanmamasıdır.
Bağımsız değişkenleri aktarmak da mümkündür:
var addition = Function("a", "b", "return a + b;");
alert(addition(5, 3)); // shows '8'
Functionsizinle yerel kapsamı kirletmeyin ve bu nedenle evalmotorlar için optimizasyonu bu kadar zorlaştırıyor ... OP örneğiyle şunu yapardım:var fnc = Function('return '+s)();
element.onclick = function() { alert("test"); }.
Oldukça yakınsın.
//Create string representation of function
var s = "function test(){ alert(1); }";
//"Register" the function
eval(s);
//Call the function
test();
İşte çalışan bir keman .
evalGelecekteki arama yapanlara zorunlu uyarı: evalbilgisayar korsanları için boşluklar açabilir: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ancak tehlikelerini biliyorsanız ve bunlardan kaçınıyorsanız, bu iyi ve basit bir yoldur. dizeden bir işlev oluşturma
Evet, kullanmak Functionharika bir çözüm ama biraz daha ileri gidip dizeyi ayrıştırıp gerçek JavaScript işlevine dönüştüren evrensel ayrıştırıcı hazırlayabiliriz ...
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;
};
}
kullanım örnekleri:
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();
işte jsfiddle
JavaScriptFunctionvar name = "foo";
// Implement it
var func = new Function("return function " + name + "(){ alert('hi there!'); };")();
// Test it
func();
// Next is TRUE
func.name === 'foo'
Kaynak: http://marcosc.com/2012/03/dynamic-function-names-in-javascript/
evalvar name = "foo";
// Implement it
eval("function " + name + "() { alert('Foo'); };");
// Test it
foo();
// Next is TRUE
foo.name === 'foo'
sjsClasshttps://github.com/reduardo7/sjsClass
Class.extend('newClassName', {
__constructor: function() {
// ...
}
});
var x = new newClassName();
// Next is TRUE
newClassName.name === 'newClassName'
Bu teknik nihayetinde eval yöntemine eşdeğer olabilir, ancak bazıları için yararlı olabileceği için eklemek istedim.
var newCode = document.createElement("script");
newCode.text = "function newFun( a, b ) { return a + b; }";
document.body.appendChild( newCode );
Bu, işlevsel olarak bu <script> öğesini belgenizin sonuna eklemeye benzer, örneğin:
...
<script type="text/javascript">
function newFun( a, b ) { return a + b; }
</script>
</body>
</html>
new Function()İçeride bir dönüş ile kullanın ve hemen uygulayın.
var s = `function test(){
alert(1);
}`;
var new_fn = new Function("return " + s)()
console.log(new_fn)
new_fn()
Dinamik bağımsız değişkenlere sahip bir örnek:
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]))