假设我有一个类似下面的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)
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().这是一个很快的例子.
小智 11
使用括号.
var fn = eval("(function() {...})");
Run Code Online (Sandbox Code Playgroud)
此技术也适用于传输JSON值.
顺便说一句,通过直接从其他函数编写函数来构建函数通常更好.如果您使用字符串,则必须担心意外变量捕获等问题.
这是我在简单情况下使用的:
// 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)
您还可以将字符串插入到脚本元素中,然后将脚本元素插入到页面中。
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)