【问题标题】:Call Function as String [duplicate]以字符串形式调用函数[重复]
【发布时间】:2013-06-03 11:08:37
【问题描述】:

我有一个字符串是我的 javaScript 函数:

var foo = "CONCATENATE('a', ' ', 'b')";

如何在不使用eval()的情况下使这个函数的javascript调用?

【问题讨论】:

  • 这就是eval 的用途......以及任何其他名称的玫瑰............我会尝试重构以避免将所有这些数据放在一个字符串中。跨度>
  • 我会看看你为什么需要这样做,并考虑重新设计。正如昆汀所说,虽然 eval 是邪恶的,但这正是它的目的。只需确保字符串不是来自用户输入即可。
  • 您可以建立一个可能函数的“白名单”并自己解析字符串。大量的工作和重新发明轮子,但它会奏效。
  • 在 javascript 中,没有 eval() 就无法使用字符串作为代码;

标签: javascript


【解决方案1】:

:) 这是一个有趣的问题。让我一步一步来。这将无法处理所有内容,只能处理带有字符串参数的函数。

这是一个带有一些基本代码的 jsFiddle:http://jsfiddle.net/Sqa8L/

请注意,我根本没有对其进行测试,因此请谨慎使用。

第 1 步:使用正则表达式获取函数名称

理想情况下,我建议使用某种解析器来获得更可靠的结果,但我认为,一旦您了解了一般概念,您就可以继续执行此答案。所以,首先是正则表达式:

var matchFnName = /^([^(]+)\(([^)]+)\)/.exec(str);

这将为您提供两个匹配项,一个用于函数名称,第二个用于整个参数列表。 (除非你有复杂的表达式,在这种情况下,它会失败:))。

提取参数

我刚刚使用简单的语句进行了拆分:

var paramList = paramListStr.split(',');

如果任何字符串包含“,”,这将失败。您将需要更好的解析技术来处理这个问题。

在对象上调用函数

您需要发送一个响应函数调用的对象,或者它默认为全局范围。

onObject[fnName].apply(onObject, paramList);

查看申请here。基本上,apply 所做的是调用第一个参数onObject 中提供的对象上的函数,并在第二个参数paramList 中传递一个参数列表。

希望这有助于您开始大方向。

【讨论】:

  • 我希望有一些 JavaScript foo 魔法可以为我解决这个问题 :)
  • 我会标记为已解决,因为这是最好的解决方案
【解决方案2】:

无论您将使用哪种解决方案,它都会在 javascript 级别隐式或显式调用 eval(),或者在引擎级别等效。

【讨论】:

  • 为什么要投反对票?也许我没有说清楚 - eval() 是一个内置函数,它将字符串参数作为源代码执行。如果您可以向我展示一种更强大或更安全的方式来在 javascript 中执行字符串,我会接受这个 downwote。如果一无所获,任何开发人员都不应该“重新发明轮子”。
猜你喜欢
  • 2014-01-29
  • 2015-09-14
  • 1970-01-01
  • 2019-07-16
  • 2021-06-03
  • 2016-07-30
  • 2012-12-31
  • 2016-12-20
  • 2016-11-23
相关资源
最近更新 更多