Answers:
我添加了jsperf测试,以4种不同的方式从string创建函数:
将RegExp与Function类一起使用
var func = "function (a, b) { return a + b; }".parseFunction();
将Function类与“ return”一起使用
var func = new Function("return " + "function (a, b) { return a + b; }")();
使用官方的Function构造函数
var func = new Function("a", "b", "return a + b;");
使用评估
eval("var func = function (a, b) { return a + b; };");
从字符串创建函数的更好方法是使用Function
:
var fn = Function("alert('hello there')");
fn();
这具有优点/缺点,即当前范围内的变量(如果不是全局变量)不适用于新构造的函数。
也可以传递参数:
var addition = Function("a", "b", "return a + b;");
alert(addition(5, 3)); // shows '8'
Function
您不会污染本地范围,这就是为什么eval
使引擎难以优化的原因...对于OP示例,我将:var fnc = Function('return '+s)();
element.onclick = function() { alert("test"); }
。
你很亲密
//Create string representation of function
var s = "function test(){ alert(1); }";
//"Register" the function
eval(s);
//Call the function
test();
这是工作中的小提琴。
eval
对未来的搜索者的强制性警告:eval
可能会为黑客带来漏洞:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference / ...但是,如果您知道它的危险并且可以避免它们,那么这是一种很好的简单方法从字符串创建函数
是的,using Function
是一个很好的解决方案,但是我们可以做得更进一步,准备通用的解析器来解析字符串并将其转换为真正的JavaScript函数...
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;
};
}
用法示例:
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();
这里是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'
资源: 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'
这项技术最终可能等效于eval方法,但是我想添加它,因为它可能对某些人有用。
var newCode = document.createElement("script");
newCode.text = "function newFun( a, b ) { return a + b; }";
document.body.appendChild( newCode );
这在功能上类似于将此<script>元素添加到文档的末尾,例如:
...
<script type="text/javascript">
function newFun( a, b ) { return a + b; }
</script>
</body>
</html>
一个带有动态参数的示例:
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]))