调用绕过 eval() 的函数

Calling a function bypassing eval()

我正在使用使用 eval 函数的 Javascript 代码。

eval(myString)

myString = myFunc(arg)的值,我想不使用eval直接调用myFunc

我无法控制要调用的函数,因为我将该函数作为字符串(此处为 myString)获取。 该函数的参数也是同一字符串的一部分。

那么,有什么方法可以在不使用 eval 的情况下调用预期的函数吗?

JavaScript 不提供任何调用表示为字符串的函数的方法,除了使用 eval。不过,使用它并没有错。鉴于您别无选择。

或许您可以尝试使用 Function:

var sure = function(s) {
  return confirm(s);
};
var str = 'sure("Are you sure?")';
var rtn = new Function('return ' + str)();
alert(rtn);

我有点怀疑是否允许用户提供函数名,但是...假设您在变量中有函数名,在变量中有 arg 的值。繁荣:

var myString = window[fn](arg);

arg 大概已经在争论中了,所以这很简单。下一部分是提取函数名称。只是一些正则表达式:

var fn = /^([a-z0-9_]+)\(arg\)$/i.exec(str)[1];
if (fn && typeof window[fn] === 'function') {
  window[fn](arg);
}

这当然假设该函数始终在全局范围内,但如果不是,您应该能够相应地进行调整。另外,我的正则表达式只是我想到的第一件事。它可能没有涵盖所有可能的函数名称。

如果你想将字符串限制为仅一组特定的函数(你几乎肯定应该这样做),一旦你有了函数名,这也变得非常容易:

var allowedFunctions = {fn1: fn1, fn2: fn2, someOtherFunction: function() {} },
    fn = /^([a-z0-9_]+)\(arg\)$/i.exec(str)[1];

if (fn && allowedFunctions[fn]) {
    allowedFunctions[fn](arg);
} else {
    // Hah, nice try.
}

(如果 arg 实际上不是变量名,而是某种文字或任意表达式,这会变得有点复杂,安全性也会大大降低。)