有没有办法用javascript从字符串创建函数?

IT技术 javascript string function
2021-02-08 16:18:40

例如;

var s = "function test(){
  alert(1);
}";

var fnc = aMethod(s);

如果这是字符串,我想要一个名为 fnc 的函数。fnc();弹出警报屏幕。

eval("alert(1);") 不能解决我的问题。

6个回答

从字符串创建函数的更好方法是使用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)();
2021-03-20 16:18:40
@RyanGriggs 在您的情况下,您不需要“eval”功能,因此最好将其编写为element.onclick = function() { alert("test"); }.
2021-04-01 16:18:40
从我的例子来看,你是对的。但是,如果您想分配存储在字符串中的任意函数,您的方法是完美的。这就是我真正想要做的。我有多个函数存储在字符串变量中,并且想将一个函数分配给一个 onclick 操作。
2021-04-04 16:18:40
我认为这可能应该是公认的答案。它比 eval() 安全得多。
2021-04-07 16:18:40
你,我的朋友,值得很多赞。这具有创建可以分配给事件等的函数对象的优点。例如: element.onclick = Function("alert('test');");
2021-04-07 16:18:40

我为 4 种不同的方法添加了一个 jsperf 测试来从字符串创建一个函数:

  • 将 RegExp 与 Function 类一起使用

    var func = "function (a, b) { return a + b; }".parseFunction();

  • 使用带有“返回”的函数类

    var func = new Function("return " + "function (a, b) { return a + b; }")();

  • 使用官方函数构造函数

    var func = new Function("a", "b", "return a + b;");

  • 使用评估

    eval("var func = function (a, b) { return a + b; };");

http://jsben.ch/D2xTG

2个结果样本: 在此处输入图片说明 在此处输入图片说明

@KthProg 冷静下来;)。它并不总是很糟糕,像这种情况,此时jsperf是停机的,幸运的是我在它停机之前添加了结果截图,当我收到Bulk的评论时。
2021-03-17 16:18:40
@KthProg 仅供参考,这是由审核系统生成的预设响应:) 它在队列中弹出,我们检查预定问题,此评论旨在修复其中一个问题。这不是一个硬性规定,您会注意到评论是以建议的形式而不是命令的形式。
2021-03-18 16:18:40

你很接近。

//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/...但如果你知道它的危险并且可以避免它们,那么这是一个很好的简单方法从字符串创建函数
2021-03-18 16:18:40
如果您没有函数名称,因为它来自数据库记录怎么办?
2021-04-02 16:18:40
我知道该函数已声明,但无法猜测调用函数名称。非常感谢。
2021-04-04 16:18:40

是的,使用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

嗨,请支持此方法的箭头功能支持吗?
2021-03-12 16:18:40
我在 typescirpt 中收到此错误“类型 'String' 上不存在属性 'parseFunction'。”
2021-04-05 16:18:40

动态函数名 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/redardo7/sjsClass

例子

Class.extend('newClassName', {
    __constructor: function() {
        // ...
    }
});

var x = new newClassName();
// Next is TRUE
newClassName.name === 'newClassName'