如何在不使用eval的情况下调用下面的胖箭头函数(存储在字符串中)?
"g => { alert(g); }"
使用eval,下面的代码工作正常,但我想避免使用eval。
eval("g => { alert(g); }")('hello')
我希望我能用“新功能”做下面的事情,但到目前为止我没有运气。
new Function("g => { alert(g); }")('hello')
非常感谢。
答案 0 :(得分:1)
来自MDN
Function构造函数创建一个新的Function对象。直接调用构造函数可以动态创建函数,但是遇到类似于 eval 的安全性和性能问题。
表示,您可以轻松地解析字符串以使用函数构造函数,例如:
const str = [g,body] = "g => { console.log(g); }".split(" => ");
var myFunc = new Function(g, body);
myFunc("hello");
const str2 = [args,body] = "(h,i) => {console.log(h,i);}".split(" => ");
const [h,i] = args.replace(/\(|\)/g,"").split(",");
var myFunc2 = new Function(h,i, body);
myFunc2("hello","buddy");

答案 1 :(得分:1)
你做的任何事情,包括你自己的JS解释器,都将是eval
的功能等同。调用eval()
函数本身并不是一个安全漏洞。执行未经过处理的代码是一个安全问题,而这正是您在此尝试做的事情。 使用eval
或任何等效的会造成XSS漏洞。
如果您使用JS编写的真实解释器,您可能能够对代码进行沙箱化并降低风险,但它仍然是一个灰色区域。
OTOH,如果您有充分的理由认为有问题的代码需要消毒,那么就没有理由不使用eval
。
请注意,您无法可靠地清理JS代码。 Anything can be done with very little JS syntax available,所以代码来自受信任的来源,或者永远不应该运行。
所有这些,也许用new Function
编译函数的最简单方法是
(new Function('return ('+code+')'))()
这几乎完全等同于调用eval(code)
,只是没有访问本地命名空间。直接使用eval()
应该稍快一些(省略创建不必要的函数对象)。
答案 2 :(得分:0)
var fatso = "g => { alert(g); }";
var s = document.createElement("script");
s.innerText = "function callMe(f) { var a = " + fatso + "; a(f) }"
document.head.appendChild(s);
callMe("hello");