假设我们有一个如下所示的函数:
const fn = () => x;
Run Code Online (Sandbox Code Playgroud)
此函数应返回全局范围中可用的xwhere 值x.最初这是undefined但如果我们定义x:
const x = 42;
Run Code Online (Sandbox Code Playgroud)
然后我们可以期待fn回来42.
现在让我们说我们想要渲染fn为一个字符串.在JavaScript中,我们toString为此目的.但是,我们还要说我们最终要fn在新的上下文中执行(即使用eval),因此它使用的任何全局引用都应该在调用之前或期间内化toString.
我们如何创建x一个局部变量,其值反映了x我们转换fn为字符串时的全局值?假设我们不知道x是否被命名x.也就是说我们可以假设变量包含在同一个模块中.
我们无法知道x其名字x。这是这个难题的核心部分,因此在原始问题中以粗体显示。虽然如果我们有一个更简单的解决方案就好了,但似乎正确的答案归结为实现某种解析器或 AST 遍历。
为什么这是必要的?虽然我们可以假设它x作为全局变量存在于模块中(它必然在函数之间共享),但我们不能假设它有一个已知的名称。因此,我们需要某种方法x从我们的模块中提取(或所有全局变量),然后在最终时将其提供为上下文eval。
注意:提供已知变量作为上下文是微不足道的。这里的几个答案似乎认为这是一个困难的问题,但事实上它很容易解决eval;只需将上下文作为字符串添加到前面即可。
那么这里的正确答案是什么呢?如果我们要使用 AST(例如,Acorn可能是一个可行的起点),我们可以检查该模块并以编程方式提取其中的所有全局变量。这包括x或任何其他可能在我们的函数之间共享的变量;我们甚至可以检查函数以确定哪些变量是其执行所必需的。
同样,最初提出这个问题的希望是提炼出一个更简单的解决方案或揭示可能适合我们的需求的现有技术。最终,我的答案和我接受的答案都归结为从 JavaScript 模块解析和提取全局变量的重要任务;似乎没有一个简单的方法。我认为这是一个公平的答案,即使不是我们今天要实施的实际答案。(不过,随着项目的发展,我们稍后会解决这个问题。)
| 归档时间: |
|
| 查看次数: |
407 次 |
| 最近记录: |