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

ymu*_*tlu 94 javascript string function

例如;

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

var fnc = aMethod(s);
Run Code Online (Sandbox Code Playgroud)

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

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

Lek*_*eyn 167

从字符串创建函数的更好方法是使用Function:

var fn = Function("alert('hello there')");
fn();
Run Code Online (Sandbox Code Playgroud)

这具有优点/缺点,即当前范围中的变量(如果不是全局的)不适用于新构造的函数.

传递参数也是可能的:

var addition = Function("a", "b", "return a + b;");
alert(addition(5, 3)); // shows '8'
Run Code Online (Sandbox Code Playgroud)

  • 同意,使用`Function`你不会污染本地范围,这就是为什么`eval`使引擎的优化变得如此困难......使用OP示例,我会:`var fnc = Function('return'+ s) ();` (5认同)

phn*_*nah 61

我添加了一个jsperf测试,用于从string创建函数的4种不同方法:

  • 将RegExp与Function类一起使用

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

  • 使用带有"返回"的Function类

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

  • 使用官方Function构造函数

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

  • 使用Eval

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

http://jsben.ch/D2xTG

2结果样本: 在此输入图像描述 在此输入图像描述


Jam*_*ill 38

你很亲密.

//Create string representation of function
var s = "function test(){  alert(1); }";

//"Register" the function
eval(s);

//Call the function
test();
Run Code Online (Sandbox Code Playgroud)

这是一个工作小提琴.

  • 强制性`eval`警告未来搜索:`eval`可以打开黑客漏洞:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval但如果你知道它的危险,可以避免它们,那么这是一个从字符串创建函数的简单方法 (4认同)

Mr.*_*kin 13

是的,使用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;
    };
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

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();
Run Code Online (Sandbox Code Playgroud)

是jsfiddle


Edu*_*omo 11

动态函数名称 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'
Run Code Online (Sandbox Code Playgroud)

资料来源: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'
Run Code Online (Sandbox Code Playgroud)

运用 sjsClass

https://github.com/reduardo7/sjsClass

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

var x = new newClassName();
// Next is TRUE
newClassName.name === 'newClassName'
Run Code Online (Sandbox Code Playgroud)


Dav*_*rry 5

这种技术可能最终等同于eval方法,但我想添加它,因为它可能对某些人有用.

var newCode = document.createElement("script");

newCode.text = "function newFun( a, b ) { return a + b; }";

document.body.appendChild( newCode );
Run Code Online (Sandbox Code Playgroud)

这在功能上就像将<script>元素添加到文档的末尾,例如:

...

<script type="text/javascript">
function newFun( a, b ) { return a + b; }
</script>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)


Fer*_*jal 5

使用new Function()内部带有 return 的 并立即执行。

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

var new_fn = new Function("return " + s)()
console.log(new_fn)
new_fn()
Run Code Online (Sandbox Code Playgroud)