给定一个描述Javascript函数的字符串,将其转换为Javascript函数

bra*_*jam 44 javascript

假设我有一个类似下面的Javascript字符串

var fnStr = "function(){blah1;blah2;blah3; }" ;
Run Code Online (Sandbox Code Playgroud)

(这可能来自用户输入的表达式,正确消毒,或者可能是某些符号计算的结果.这无关紧要).

我想定义fn好像我的代码中有以下行:

var fn = function(){blah1;blah2;blah3; } ;
Run Code Online (Sandbox Code Playgroud)

我怎么做?

我提出的最好的是以下内容:

var fn = eval("var f = function(){ return "+fnStr+";}; f() ;") ;
Run Code Online (Sandbox Code Playgroud)

这似乎是诀窍,即使它使用了可怕的eval(),并使用了一个稍微复杂的论点.我可以做得更好吗?即要么不使用eval(),要么提供更简单的参数?

goa*_*oat 63

还有Function对象.

var adder = new Function("a", "b", "return a + b");
Run Code Online (Sandbox Code Playgroud)

  • **(与eval的区别)***"注意:使用Function构造函数创建的函数不会为其创建上下文创建闭包;它们始终在全局范围内创建.运行它们时,**它们只能访问它们自己的局部变量和全局变量,而不是调用Function构造函数的范围**.这与使用eval和函数表达式的代码不同."* (7认同)
  • JSLint抛出了一个简洁的"函数构造函数是eval".我一直在寻找一种能让Crockford安抚的解决方案. (2认同)

Nic*_*ver 26

你可以这样做:

//in your case: eval("var fn = " + fnStr);
eval("var fn = function(){ blah1;blah2;blah3; }"); 
fn();
Run Code Online (Sandbox Code Playgroud)

不知道如何更简单,有时没有(更好)的方式eval().这是一个很快的例子.

  • 使用 Function 对象而不是 eval 语句来避免代码异味。 (2认同)

小智 11

使用括号.

var fn = eval("(function() {...})");
Run Code Online (Sandbox Code Playgroud)

此技术也适用于传输JSON值.

顺便说一句,通过直接从其他函数编写函数来构建函数通常更好.如果您使用字符串,则必须担心意外变量捕获等问题.


Jul*_* TF 6

这是我在简单情况下使用的:

// an example function
function plus(...args) {
    return args.reduce( (s,v) => s+v, 0 );
}

// function to string
let str = plus.toString();

// string to function
let copy = new Function('return ' + str)();

// tests
console.assert(plus.name == 'plus');
console.assert(copy.name == 'plus');
console.assert(plus.constructor == Function);
console.assert(copy.constructor == Function);
console.assert(plus(1,2,3,4) === copy(1,2,3,4));
console.assert(plus.toString() === copy.toString());
Run Code Online (Sandbox Code Playgroud)

  • 处理这个问题的最佳、最安全的方法 (2认同)

use*_*003 5

您还可以将字符串插入到脚本元素中,然后将脚本元素插入到页面中。

script_ele = window.document.createElement("script");
script_ele.innerHTML = 'function my_function(){alert("hi!");}';
window.document.body.appendChild(script_ele);
my_function();
Run Code Online (Sandbox Code Playgroud)