【问题标题】:Given a string describing a Javascript function, convert it to a Javascript function给定一个描述 Javascript 函数的字符串,将其转换为 Javascript 函数
【发布时间】:2010-04-04 04:19:12
【问题描述】:

假设我有一个如下所示的 Javascript 字符串

var fnStr = "function(){blah1;blah2;blah3; }" ;

(这可能来自用户输入的、经过适当清理的表达式,也可能是某些符号计算的结果。这真的没关系)。

我想定义fn,就好像以下行在我的代码中一样:

var fn = function(){blah1;blah2;blah3; } ;

我该怎么做?

我想出的最好的如下:

var fn = eval("var f = function(){ return "+fnStr+";}; f() ;") ;

这似乎可以解决问题,尽管它使用了可怕的eval(),并且使用了一个稍微复杂的参数。我能做得更好吗? IE。要么不使用eval(),要么提供一个更简单的参数?

【问题讨论】:

  • 一般evalevil ;-)

标签: javascript


【解决方案1】:

还有Function 对象。

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

【讨论】:

  • 不错!这更符合我最初寻找的内容。
  • JSLint 抛出一个精辟的“函数构造函数是 eval”。我仍在寻找能够安抚 Crockford 的解决方案。
  • (与 eval 的区别) “注意:使用 Function 构造函数创建的函数不会为其创建上下文创建闭包;它们总是在全局范围内创建。运行它们时,它们将只能访问它们自己的局部变量和全局变量,而不是调用 Function 构造函数的范围内的变量。这与使用 eval 和代码不同函数表达式。”
  • 不使用eval()或者Function构造函数可以吗?
  • @Ozil 不,这没有意义。您需要将字符串表示形式转换为函数。这需要使用可以将字符串评估为 javascript 代码的东西。评估/函数并不总是邪恶的/他们的威胁被严重夸大了。
【解决方案2】:

你可以这样做:

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

不知道如何让它变得更简单,有时在eval() 周围没有(更好的)方法。这是quick example of this in action

【讨论】:

  • 是的,我不认为它可以变得更简单,但这出于某种原因让我逃脱了。谢谢。
  • 哇,这是一个伟大的救生员.. 非常感谢.. 赞成.. :)
  • 使用 Function 对象而不是 eval 语句来避免代码异味。
【解决方案3】:

使用括号。

var fn = eval("(function() {...})");

这种技术也适用于传输 JSON 值。

顺便说一句,通过直接从其他函数组合函数来构建函数通常会更好。如果您使用的是字符串,则必须担心诸如意外variable capture 之类的事情。

【讨论】:

  • 如果您必须将函数完全作为字符串传递,这个方法实际上是最有用的。
【解决方案4】:

这是我用于简单情况的方法:

// 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());

【讨论】:

  • 处理此问题的最佳、最安全的方法
【解决方案5】:

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

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

【讨论】:

  • 这是一个聪明的解决方案!
【解决方案6】:

Function 构造函数创建一个新的 Function 对象。在 JavaScript 中,每个函数实际上都是一个 Function 对象。

// Create a function that takes two arguments and returns the sum of those arguments
var fun = new Function("a", "b", "return a + b");
// Call the function
fun(2, 6);
Output: 8

【讨论】:

    【解决方案7】:

    一种方式:

         var a = 'function f(){ alert(111); } function d(){ alert(222);}';  
         eval(a);
         d();
         
    

    将字符串转换为函数的第二种更安全的方法:

         // function name and parameters to pass
        var fnstring = "runMe";
        var fnparams = ["aaa", "bbbb", "ccc"];
        
        // find object
        var fn = window[fnstring];
        
        // is object a function?
        if (typeof fn === "function") fn.apply(null, fnparams);
        
        
        function runMe(a,b){
          alert(b);
        }
    

    查看工作代码:http://plnkr.co/edit/OiQAVd9DMV2PfK0NG9vk

    【讨论】:

      【解决方案8】:

      您可以调用 Parse your string as javascript 函数

      1. function getDate(){alert('done')} // 假设这是你定义的函数

      调用上述函数 getDate() 是这样的字符串格式,如 'getDate()'

      1. var callFunc=new Function('getDate()') //解析并注册你的函数

      2. callFunc() // 调用函数

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-04
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多