gpt4 book ai didi

javascript - 评估以字符串形式给出的函数调用,该字符串使用 'require' 声明

转载 作者:行者123 更新时间:2023-11-30 14:13:03 24 4
gpt4 key购买 nike

我需要使用一个只能在引号中访问的函数,因此它是一个字符串。

假设函数名为“m”。该函数是一个 NPM 包。我使用“require”将其导入到我的项目中。

假设字符串是另一个函数给我的。因此我没有机会简单地删除引号。

const m = require('mithril')
let vnode = "m('p', 'text')" // I need this string as a function

我通过网络进行了搜索,得出了两个答案。使用 eval() 或 Function()。

现在,eval 可以正常工作了。然而,我发现很多人一直在说 eval() 是邪恶的、缓慢的,即使我认为是时候使用它也应该避免。我正在尝试在 github 页面上构建一个单页应用程序 - 仅供引用 - 也许 eval() 在这种情况下可以使用。

Function() 表现得很奇怪。当我执行 Function("m('p', 'text')") 时,它返回这个(作为字符串):

function anonymous( ) { m("p", "text" ) }

...当我调用它时 Function("m('p', 'text')")(),它返回一个错误,说:

ReferenceError: m is not defined

我试图在 Function() 调用中再次require 模块 mithril ,但是这次它给出了一个错误,指出 require 未定义。我认为这是因为 Function 来自不同的环境而不是来自 Nodejs。

我只是期待 eval 函数的行为,而不用担心被黑客攻击。

有什么想法吗?

编辑(进一步解释):

我注意到我在 X/Y 问题中问 Y。这是我的问题的 X。

我正在使用 Mithril JS 将单页应用程序部署到 github 页面. ( my repo )

我需要渲染数学表达式,其中 KaTeX进来了。

KaTeX 自带 a simple API , renderToString() 函数返回一个 HTML 元素,该元素呈现为呈现良好的数学表达式。

另一方面,Mithril JS 渲染了 VNodes,一种描述 HTML 标签的特殊功能。示例:

<div class="cont">
<p>
Text
</p>
</div>

... 当转换为 vnodes ...

m('div', {class:'cont'}, [
m('p', 'Text')
])

现在,为了 Mithril 能够正确查看 KaTeX 的 HTML 输出,html 标签应该被翻译成 Vnodes。我找到了一个 converter here

我将转换器的代码添加到我的项目中并将其作为函数导入。我在这里面临的问题是转换器完美地将 HTML 结构转换为 VNode,但它以字符串形式返回它们,并用引号引起来...

我能想到的解决方案:

  • 将另一个包添加到我的项目中,允许 Mithril 使用 JSX 语法,其中 JS 可以在 HTML 标记中穿插编写。这是我最后的选择,但我个人不喜欢 JSX 语法,因为它只是一种权衡。
  • 使用 eval() 函数,它完美地完成了我想要的,但安全问题是众所周知的。

还有其他想法吗?

最佳答案

将类似 eval 的字符串转换为参数数组,然后使用这些参数调用 m 可能会更优雅。例如,如果参数始终是用 's 分隔的字符串:

// const m = require('mithril')
// for demonstration purposes:
const m = (...args) => console.log('called with ' + args.join(','));

const vnode = "m('p', 'text')"
let match;
const pattern = /'([^']+)'/g;
const args = [];
while (match = pattern.exec(vnode)) {
args.push(match[1]);
}
m.apply(undefined, args);

如果函数名称也可以变化,则使用带有 m 键的对象而不是独立变量:

// const m = require('mithril')
// for demonstration purposes:
const fns = {
m: (...args) => console.log('called with ' + args.join(','))
};

const vnode = "m('p', 'text')";
const fnName = vnode.match(/^[^(]+/)[0];
let match;
const pattern = /'([^']+)'/g;
const args = [];
while (match = pattern.exec(vnode)) {
args.push(match[1]);
}
fns[fnName].apply(undefined, args);

关于javascript - 评估以字符串形式给出的函数调用,该字符串使用 'require' 声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54058166/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com